summaryrefslogtreecommitdiff
path: root/sc/source
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source')
-rw-r--r--sc/source/core/data/cell2.cxx4
-rw-r--r--sc/source/core/data/column2.cxx17
-rw-r--r--sc/source/core/data/documen2.cxx7
-rw-r--r--sc/source/core/data/documen3.cxx29
-rwxr-xr-xsc/source/core/data/documen9.cxx22
-rw-r--r--sc/source/core/data/dpobject.cxx52
-rw-r--r--sc/source/core/data/dpsave.cxx63
-rw-r--r--sc/source/core/data/dpsdbtab.cxx2
-rw-r--r--sc/source/core/data/dpshttab.cxx12
-rw-r--r--sc/source/core/data/dptablecache.cxx44
-rw-r--r--sc/source/core/data/drwlayer.cxx24
-rw-r--r--sc/source/core/data/table2.cxx34
-rw-r--r--sc/source/core/data/table4.cxx261
-rw-r--r--sc/source/core/inc/interpre.hxx1
-rw-r--r--sc/source/core/tool/address.cxx8
-rw-r--r--sc/source/core/tool/compiler.cxx47
-rw-r--r--sc/source/core/tool/dbcolect.cxx23
-rw-r--r--sc/source/core/tool/interpr1.cxx260
-rw-r--r--sc/source/core/tool/interpr3.cxx252
-rwxr-xr-xsc/source/core/tool/interpr4.cxx48
-rw-r--r--sc/source/core/tool/token.cxx25
-rw-r--r--sc/source/filter/xml/xmlexprt.cxx3
-rw-r--r--sc/source/filter/xml/xmlimprt.cxx13
-rw-r--r--sc/source/filter/xml/xmlsubti.cxx3
-rw-r--r--sc/source/filter/xml/xmltabi.cxx28
-rw-r--r--sc/source/ui/app/inputhdl.cxx9
-rw-r--r--sc/source/ui/dbgui/pvfundlg.cxx7
-rw-r--r--sc/source/ui/dbgui/pvlaydlg.cxx2
-rw-r--r--sc/source/ui/docshell/docfunc.cxx2
-rw-r--r--sc/source/ui/docshell/externalrefmgr.cxx77
-rw-r--r--sc/source/ui/inc/inputhdl.hxx2
-rw-r--r--sc/source/ui/styleui/scstyles.src13
-rw-r--r--sc/source/ui/unoobj/addruno.cxx4
-rw-r--r--sc/source/ui/unoobj/docuno.cxx6
-rw-r--r--sc/source/ui/unoobj/linkuno.cxx37
-rw-r--r--sc/source/ui/view/editsh.cxx5
-rw-r--r--sc/source/ui/view/gridwin.cxx3
-rw-r--r--sc/source/ui/view/gridwin2.cxx24
-rw-r--r--sc/source/ui/view/output2.cxx38
-rw-r--r--sc/source/ui/view/tabcont.cxx5
-rw-r--r--sc/source/ui/view/viewfun3.cxx13
-rw-r--r--sc/source/ui/view/viewfun5.cxx2
42 files changed, 1013 insertions, 518 deletions
diff --git a/sc/source/core/data/cell2.cxx b/sc/source/core/data/cell2.cxx
index e4631dde2d9a..23b9934564b9 100644
--- a/sc/source/core/data/cell2.cxx
+++ b/sc/source/core/data/cell2.cxx
@@ -990,6 +990,10 @@ void ScFormulaCell::UpdateReference(UpdateRefMode eUpdateRefMode,
pUndoDoc->PutCell( aUndoPos, pFCell );
}
}
+ // #i116833# If the formula is changed, always invalidate the stream (even if the result is the same).
+ // If the formula is moved, the change is recognized separately.
+ if (bValChanged && pDocument->IsStreamValid(aPos.Tab()))
+ pDocument->SetStreamValid(aPos.Tab(), sal_False);
bValChanged = sal_False;
if ( pRangeData )
{ // Replace shared formula with own formula
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index abc82c005408..db48b58a169a 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -244,9 +244,16 @@ long ScColumn::GetNeededSize( SCROW nRow, OutputDevice* pDev,
else
bBreak = ((const SfxBoolItem&)pPattern->GetItem(ATTR_LINEBREAK)).GetValue();
- if (pCell->HasValueData())
- // Cell has a value. Disable line break.
- bBreak = false;
+ SvNumberFormatter* pFormatter = pDocument->GetFormatTable();
+ sal_uLong nFormat = pPattern->GetNumberFormat( pFormatter, pCondSet );
+ // #i111387# #o11817313# disable automatic line breaks only for "General" number format
+ if ( bBreak && pCell->HasValueData() && ( nFormat % SV_COUNTRY_LANGUAGE_OFFSET ) == 0 )
+ {
+ // also take formula result type into account for number format
+ if ( pCell->GetCellType() != CELLTYPE_FORMULA ||
+ ( static_cast<ScFormulaCell*>(pCell)->GetStandardFormat(*pFormatter, nFormat) % SV_COUNTRY_LANGUAGE_OFFSET ) == 0 )
+ bBreak = false;
+ }
// get other attributes from pattern and conditional formatting
@@ -332,8 +339,6 @@ long ScColumn::GetNeededSize( SCROW nRow, OutputDevice* pDev,
{
String aValStr;
Color* pColor;
- SvNumberFormatter* pFormatter = pDocument->GetFormatTable();
- sal_uLong nFormat = pPattern->GetNumberFormat( pFormatter, pCondSet );
ScCellFormat::GetString( pCell, nFormat, aValStr, &pColor,
*pFormatter,
sal_True, rOptions.bFormula, ftCheck );
@@ -497,8 +502,6 @@ long ScColumn::GetNeededSize( SCROW nRow, OutputDevice* pDev,
else
{
Color* pColor;
- SvNumberFormatter* pFormatter = pDocument->GetFormatTable();
- sal_uLong nFormat = pPattern->GetNumberFormat( pFormatter, pCondSet );
String aString;
ScCellFormat::GetString( pCell, nFormat, aString, &pColor,
*pFormatter,
diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx
index 44f7e6722d69..e0242ab90305 100644
--- a/sc/source/core/data/documen2.cxx
+++ b/sc/source/core/data/documen2.cxx
@@ -447,7 +447,12 @@ ScDocument::~ScDocument()
delete pChangeViewSettings; // und weg damit
delete pVirtualDevice_100th_mm;
- delete pDPCollection;
+ if (pDPCollection)
+ {
+ pDPCollection->FreeAll();
+ RemoveUnusedDPObjectCaches();
+ delete pDPCollection;
+ }
// delete the EditEngine before destroying the xPoolHelper
delete pCacheFieldEditEngine;
diff --git a/sc/source/core/data/documen3.cxx b/sc/source/core/data/documen3.cxx
index e249d7f3bf47..3f8742ee1d56 100644
--- a/sc/source/core/data/documen3.cxx
+++ b/sc/source/core/data/documen3.cxx
@@ -2,7 +2,7 @@
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
- * Copyright 2000, 2010 Oracle and/or its affiliates.
+ * Copyright 2000, 2011 Oracle and/or its affiliates.
*
* OpenOffice.org - a multi-platform office productivity suite
*
@@ -197,6 +197,14 @@ ScDBData* ScDocument::GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nC
return NULL;
}
+ScDBData* ScDocument::GetFilterDBAtTable(SCTAB nTab) const
+{
+ if (pDBCollection)
+ return pDBCollection->GetFilterDBAtTable(nTab);
+ else
+ return NULL;
+}
+
ScDPCollection* ScDocument::GetDPCollection()
{
if (!pDPCollection)
@@ -1359,6 +1367,20 @@ sal_Bool ScDocument::GetFilterEntries(
SCCOL nEndCol;
SCROW nEndRow;
pDBData->GetArea( nAreaTab, nStartCol, nStartRow, nEndCol, nEndRow );
+
+ //Add for i85305
+ SCCOL nTmpStartCol = nCol;
+ SCROW nTmpStartRow = nRow;
+ SCCOL nTmpEndCol = nCol;
+ SCROW nTmpEndRow = nRow;
+ GetDataArea( nTab, nTmpStartCol, nTmpStartRow, nTmpEndCol, nTmpEndRow, sal_False, false);
+ if (nTmpEndRow > nEndRow)
+ {
+ nEndRow = nTmpEndRow;
+ pDBData->SetArea(nAreaTab, nStartCol,nStartRow, nEndCol,nEndRow);
+ }
+ //End of i85305
+
if (pDBData->HasHeader())
++nStartRow;
@@ -2098,7 +2120,7 @@ void ScDocument::RemoveDPObjectCache( long nID )
void ScDocument::RemoveUnusedDPObjectCaches()
{
- for ( std::list<ScDPTableDataCache*>::iterator iter = m_listDPObjectsCaches.begin(); iter!=m_listDPObjectsCaches.end(); iter++ )
+ for ( std::list<ScDPTableDataCache*>::iterator iter = m_listDPObjectsCaches.begin(); iter!=m_listDPObjectsCaches.end(); )
{
long nID = (*iter)->GetId();
sal_uInt16 nCount = GetDPCollection()->GetCount();
@@ -2111,10 +2133,11 @@ void ScDocument::RemoveUnusedDPObjectCaches()
if ( i == nCount )
{
ScDPTableDataCache* pCache = *iter;
- m_listDPObjectsCaches.erase( iter );
+ iter = m_listDPObjectsCaches.erase( iter );
delete pCache;
continue;
}
+ ++iter;
}
}
diff --git a/sc/source/core/data/documen9.cxx b/sc/source/core/data/documen9.cxx
index 7d66ece8c570..4ca9b14d8f5d 100755
--- a/sc/source/core/data/documen9.cxx
+++ b/sc/source/core/data/documen9.cxx
@@ -111,17 +111,21 @@ void ScDocument::TransferDrawPage(ScDocument* pSrcDoc, SCTAB nSrcPos, SCTAB nDes
SdrObject* pOldObject = aIter.Next();
while (pOldObject)
{
- // #116235#
- SdrObject* pNewObject = pOldObject->Clone();
- // SdrObject* pNewObject = pOldObject->Clone( pNewPage, pDrawLayer );
- pNewObject->SetModel(pDrawLayer);
- pNewObject->SetPage(pNewPage);
+ // #i112034# do not copy internal objects (detective) and note captions
+ if ( pOldObject->GetLayer() != SC_LAYER_INTERN && !ScDrawLayer::IsNoteCaption( pOldObject ) )
+ {
+ // #116235#
+ SdrObject* pNewObject = pOldObject->Clone();
+ // SdrObject* pNewObject = pOldObject->Clone( pNewPage, pDrawLayer );
+ pNewObject->SetModel(pDrawLayer);
+ pNewObject->SetPage(pNewPage);
- pNewObject->NbcMove(Size(0,0));
- pNewPage->InsertObject( pNewObject );
+ pNewObject->NbcMove(Size(0,0));
+ pNewPage->InsertObject( pNewObject );
- if (pDrawLayer->IsRecording())
- pDrawLayer->AddCalcUndo( new SdrUndoInsertObj( *pNewObject ) );
+ if (pDrawLayer->IsRecording())
+ pDrawLayer->AddCalcUndo( new SdrUndoInsertObj( *pNewObject ) );
+ }
pOldObject = aIter.Next();
}
diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx
index c4a256b48f54..431b86d328a0 100644
--- a/sc/source/core/data/dpobject.cxx
+++ b/sc/source/core/data/dpobject.cxx
@@ -175,7 +175,8 @@ ScDPObject::ScDPObject( ScDocument* pD ) :
nHeaderRows( 0 ),
mbHeaderLayout(false),
bRefresh( sal_False ), // Wang Xu Ming - DataPilot migration
- mnCacheId( -1) // Wang Xu Ming - DataPilot migration
+ mnCacheId( -1 ), // Wang Xu Ming - DataPilot migration
+ mbCreatingTableData( false )
{
}
@@ -197,7 +198,8 @@ ScDPObject::ScDPObject(const ScDPObject& r) :
nHeaderRows( r.nHeaderRows ),
mbHeaderLayout( r.mbHeaderLayout ),
bRefresh( r.bRefresh ), // Wang Xu Ming - DataPilot migration
- mnCacheId ( r.mnCacheId ) // Wang Xu Ming - DataPilot migration
+ mnCacheId ( r.mnCacheId ), // Wang Xu Ming - DataPilot migration
+ mbCreatingTableData( false )
{
if (r.pSaveData)
pSaveData = new ScDPSaveData(*r.pSaveData);
@@ -272,7 +274,7 @@ void ScDPObject::SetOutRange(const ScRange& rRange)
pOutput->SetPosition( rRange.aStart );
}
-void ScDPObject::SetSheetDesc(const ScSheetSourceDesc& rDesc)
+void ScDPObject::SetSheetDesc(const ScSheetSourceDesc& rDesc, bool bFromRefUpdate)
{
if ( pSheetDesc && rDesc == *pSheetDesc )
return; // nothing to do
@@ -280,7 +282,7 @@ void ScDPObject::SetSheetDesc(const ScSheetSourceDesc& rDesc)
DELETEZ( pImpDesc );
DELETEZ( pServDesc );
- delete pImpDesc;
+ delete pSheetDesc;
pSheetDesc = new ScSheetSourceDesc(rDesc);
// make valid QueryParam
@@ -292,6 +294,8 @@ void ScDPObject::SetSheetDesc(const ScSheetSourceDesc& rDesc)
pSheetDesc->aQueryParam.bHasHeader = sal_True;
InvalidateSource(); // new source must be created
+ if (!bFromRefUpdate)
+ SetCacheId( -1 ); // #i116504# don't use the same cache ID for a different range (except reference update)
}
void ScDPObject::SetImportDesc(const ScImportSourceDesc& rDesc)
@@ -306,6 +310,7 @@ void ScDPObject::SetImportDesc(const ScImportSourceDesc& rDesc)
pImpDesc = new ScImportSourceDesc(rDesc);
InvalidateSource(); // new source must be created
+ SetCacheId( -1 );
}
void ScDPObject::SetServiceData(const ScDPServiceDesc& rDesc)
@@ -416,8 +421,12 @@ void ScDPObject::CreateOutput()
ScDPTableData* ScDPObject::GetTableData()
{
- if (!mpTableData)
+ if (!mpTableData && !mbCreatingTableData)
{
+ // #i117239# While filling the cache, mpTableData is still null.
+ // Prevent nested calls from GetPivotData and similar functions.
+ mbCreatingTableData = true;
+
shared_ptr<ScDPTableData> pData;
if ( pImpDesc )
{
@@ -453,6 +462,8 @@ ScDPTableData* ScDPObject::GetTableData()
// End Comments
mpTableData = pData; // after SetCacheId
+
+ mbCreatingTableData = false;
}
return mpTableData.get();
@@ -482,16 +493,19 @@ void ScDPObject::CreateObjects()
DBG_ASSERT( !pServDesc, "DPSource could not be created" );
ScDPTableData* pData = GetTableData();
- ScDPSource* pSource = new ScDPSource( pData );
- xSource = pSource;
-
- if ( pSaveData && bRefresh )
+ if ( pData ) // nested GetTableData calls may return NULL
{
- pSaveData->Refresh( xSource );
- bRefresh = sal_False;
+ ScDPSource* pSource = new ScDPSource( pData );
+ xSource = pSource;
+
+ if ( pSaveData && bRefresh )
+ {
+ pSaveData->Refresh( xSource );
+ bRefresh = sal_False;
+ }
}
}
- if (pSaveData )
+ if ( xSource.is() && pSaveData )
pSaveData->WriteToSource( xSource );
}
else if (bSettingsChanged)
@@ -630,9 +644,12 @@ void ScDPObject::BuildAllDimensionMembers()
return;
// #i111857# don't always create empty mpTableData for external service.
- // Ideally, xSource should be used instead of mpTableData.
+ // #163781# Initialize all members from xSource instead.
if (pServDesc)
+ {
+ pSaveData->BuildAllDimensionMembersFromSource( this );
return;
+ }
pSaveData->BuildAllDimensionMembers(GetTableData());
}
@@ -739,7 +756,7 @@ void ScDPObject::UpdateReference( UpdateRefMode eUpdateRefMode,
if (aNewDesc.aQueryParam.GetEntry(i).bDoQuery)
aNewDesc.aQueryParam.GetEntry(i).nField += nDiffX;
- SetSheetDesc( aNewDesc ); // allocates new pSheetDesc
+ SetSheetDesc( aNewDesc, true ); // allocates new pSheetDesc
}
}
}
@@ -767,7 +784,7 @@ void ScDPObject::WriteRefsTo( ScDPObject& r ) const
{
r.SetOutRange( aOutRange );
if ( pSheetDesc )
- r.SetSheetDesc( *pSheetDesc );
+ r.SetSheetDesc( *pSheetDesc, true );
}
void ScDPObject::GetPositionData(const ScAddress& rPos, DataPilotTablePositionData& rPosData)
@@ -1043,6 +1060,11 @@ void ScDPObject::GetHeaderPositionData(const ScAddress& rPos, DataPilotTableHead
sal_Bool ScDPObject::GetPivotData( ScDPGetPivotDataField& rTarget,
const std::vector< ScDPGetPivotDataField >& rFilters )
{
+ // #i117239# Exit with an error if called from creating the cache for this object
+ // (don't create an empty pOutput object)
+ if (mbCreatingTableData)
+ return sal_False;
+
CreateOutput(); // create xSource and pOutput if not already done
return pOutput->GetPivotData( rTarget, rFilters );
diff --git a/sc/source/core/data/dpsave.cxx b/sc/source/core/data/dpsave.cxx
index 100db65df4b7..24df9f90b31f 100644
--- a/sc/source/core/data/dpsave.cxx
+++ b/sc/source/core/data/dpsave.cxx
@@ -34,6 +34,7 @@
#include "dpsave.hxx"
#include "dpdimsave.hxx"
+#include "dpobject.hxx" // GetMemberNames used in BuildAllDimensionMembersFromSource
#include "miscuno.hxx"
#include "scerrors.hxx"
#include "unonames.hxx"
@@ -874,6 +875,7 @@ ScDPSaveDimension* ScDPSaveData::GetDimensionByName(const String& rName)
}
ScDPSaveDimension* pNew = new ScDPSaveDimension( rName, sal_False );
aDimList.Insert( pNew, LIST_APPEND );
+ mbDimensionMembersBuilt = false; // BuildAllDimensionMembers only handles existing entries in aDimList
return pNew;
}
@@ -900,6 +902,7 @@ ScDPSaveDimension* ScDPSaveData::GetNewDimensionByName(const String& rName)
}
ScDPSaveDimension* pNew = new ScDPSaveDimension( rName, sal_False );
aDimList.Insert( pNew, LIST_APPEND );
+ mbDimensionMembersBuilt = false; // BuildAllDimensionMembers only handles existing entries in aDimList
return pNew;
}
@@ -911,6 +914,7 @@ ScDPSaveDimension* ScDPSaveData::GetDataLayoutDimension()
ScDPSaveDimension* pNew = new ScDPSaveDimension( String(), sal_True );
aDimList.Insert( pNew, LIST_APPEND );
+ mbDimensionMembersBuilt = false; // BuildAllDimensionMembers only handles existing entries in aDimList
return pNew;
}
@@ -935,6 +939,7 @@ ScDPSaveDimension* ScDPSaveData::DuplicateDimension(const String& rName)
ScDPSaveDimension* pNew = new ScDPSaveDimension( *pOld );
pNew->SetDupFlag( sal_True );
aDimList.Insert( pNew, LIST_APPEND );
+ mbDimensionMembersBuilt = false; // BuildAllDimensionMembers only handles existing entries in aDimList
return pNew;
}
@@ -958,6 +963,7 @@ ScDPSaveDimension& ScDPSaveData::DuplicateDimension( const ScDPSaveDimension& rD
ScDPSaveDimension* pNew = new ScDPSaveDimension( rDim );
pNew->SetDupFlag( sal_True );
aDimList.Insert( pNew, LIST_APPEND );
+ mbDimensionMembersBuilt = false; // BuildAllDimensionMembers only handles existing entries in aDimList
return *pNew;
}
@@ -1275,6 +1281,63 @@ void ScDPSaveData::BuildAllDimensionMembers(ScDPTableData* pData)
mbDimensionMembersBuilt = true;
}
+void ScDPSaveData::BuildAllDimensionMembersFromSource( ScDPObject* pDPObj )
+{
+ // Initialize all members like BuildAllDimensionMembers, but access only the DataPilotSource, not the table data.
+ // This could also replace BuildAllDimensionMembers, but the performance implications still have to be checked.
+ // ScDPObject is used for the helper method GetMemberNames.
+
+ if (mbDimensionMembersBuilt)
+ return;
+
+ uno::Reference<sheet::XDimensionsSupplier> xSource = pDPObj->GetSource();
+ uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
+ // GetMemberNames uses the dimension index from getElementNames
+ uno::Sequence<OUString> aDimNames = xDimsName->getElementNames();
+
+ // First, build a dimension name-to-index map.
+ typedef hash_map<OUString, long, ::rtl::OUStringHash> NameIndexMap;
+ NameIndexMap aMap;
+ long nColCount = aDimNames.getLength();
+ for (long i = 0; i < nColCount; ++i)
+ aMap.insert( NameIndexMap::value_type(aDimNames[i], i) );
+
+ NameIndexMap::const_iterator itrEnd = aMap.end();
+
+ sal_uInt32 n = aDimList.Count();
+ for (sal_uInt32 i = 0; i < n; ++i)
+ {
+ ScDPSaveDimension* pDim = static_cast<ScDPSaveDimension*>(aDimList.GetObject(i));
+ const String& rDimName = pDim->GetName();
+ if (!rDimName.Len())
+ // empty dimension name. It must be data layout.
+ continue;
+
+ NameIndexMap::const_iterator itr = aMap.find(rDimName);
+ if (itr == itrEnd)
+ // dimension name not in the data. This should never happen!
+ continue;
+
+ long nDimIndex = itr->second;
+ uno::Sequence<OUString> aMemberNames;
+ pDPObj->GetMemberNames( nDimIndex, aMemberNames );
+ sal_Int32 nMemberCount = aMemberNames.getLength();
+ for (sal_Int32 j = 0; j < nMemberCount; ++j)
+ {
+ String aMemName = aMemberNames[j];
+ if (pDim->GetExistingMemberByName(aMemName))
+ // this member instance already exists. nothing to do.
+ continue;
+
+ auto_ptr<ScDPSaveMember> pNewMember(new ScDPSaveMember(aMemName));
+ pNewMember->SetIsVisible(true);
+ pDim->AddMember(pNewMember.release());
+ }
+ }
+
+ mbDimensionMembersBuilt = true;
+}
+
bool ScDPSaveData::HasInvisibleMember(const OUString& rDimName) const
{
ScDPSaveDimension* pDim = GetExistingDimensionByName(rDimName);
diff --git a/sc/source/core/data/dpsdbtab.cxx b/sc/source/core/data/dpsdbtab.cxx
index f0e060e8cc7d..977be2e182a9 100644
--- a/sc/source/core/data/dpsdbtab.cxx
+++ b/sc/source/core/data/dpsdbtab.cxx
@@ -214,7 +214,7 @@ ScDatabaseDPData::ScDatabaseDPData(
ScDocument* pDoc,
const ScImportSourceDesc& rImport, long nCacheId /*=-1 */ ) :
ScDPTableData(pDoc, rImport.GetCacheId( pDoc, nCacheId) ),
- aCacheTable( pDoc, rImport.GetCacheId( pDoc, nCacheId))
+ aCacheTable( pDoc, GetCacheId() ) // base class ID is initialized with the GetCacheId call above
{
}
diff --git a/sc/source/core/data/dpshttab.cxx b/sc/source/core/data/dpshttab.cxx
index 33ce84cc94c2..6c376209e035 100644
--- a/sc/source/core/data/dpshttab.cxx
+++ b/sc/source/core/data/dpshttab.cxx
@@ -67,7 +67,7 @@ ScSheetDPData::ScSheetDPData( ScDocument* pD, const ScSheetSourceDesc& rDesc , l
pSpecial(NULL),
bIgnoreEmptyRows( sal_False ),
bRepeatIfEmpty(sal_False),
- aCacheTable( pD, rDesc.GetCacheId( pD, nCacheId))
+ aCacheTable( pD, GetCacheId() ) // base class ID is initialized with the GetCacheId call above
{
SCSIZE nEntryCount( aQuery.GetEntryCount());
pSpecial = new sal_Bool[nEntryCount];
@@ -291,12 +291,10 @@ sal_uLong ScSheetSourceDesc::CheckValidate( ScDocument* pDoc ) const
ScRange aSrcRange( aSourceRange);
if ( !pDoc )
return STR_ERR_DATAPILOTSOURCE;
- for(sal_uInt16 i= aSrcRange.aStart.Col();i <= aSrcRange.aEnd.Col();i++)
- {
- if ( pDoc->IsBlockEmpty( aSrcRange.aStart.Tab(),
- i, aSrcRange.aStart.Row(),i, aSrcRange.aStart.Row()))
- return STR_PIVOT_FIRSTROWEMPTYERR;
- }
+
+ // #i116457# Empty column titles were allowed before 3.3, and might be useful for hidden columns with annotations.
+ // Be compatible with 3.2: Allow empty titles, create columns with empty names, hide them in the dialogs.
+
if( pDoc->IsBlockEmpty( aSrcRange.aStart.Tab(), aSrcRange.aStart.Col(), aSrcRange.aStart.Row()+1, aSrcRange.aEnd.Col(), aSrcRange.aEnd.Row() ) )
{
return STR_PIVOT_ONLYONEROWERR;
diff --git a/sc/source/core/data/dptablecache.cxx b/sc/source/core/data/dptablecache.cxx
index 3cf40a7ab6dc..4a80f742769b 100644
--- a/sc/source/core/data/dptablecache.cxx
+++ b/sc/source/core/data/dptablecache.cxx
@@ -210,13 +210,13 @@ ScDPItemData::ScDPItemData( ScDocument* pDoc, SCROW nRow, sal_uInt16 nCol, sal_u
else if ( pDoc->HasValueData( nCol, nRow, nDocTab ) )
{
double fVal = pDoc->GetValue(ScAddress(nCol, nRow, nDocTab));
+ nNumFormat = pDoc->GetNumberFormat( ScAddress( nCol, nRow, nDocTab ) );
sal_uLong nFormat = NUMBERFORMAT_NUMBER;
if ( pFormatter )
- nFormat = pFormatter->GetType( pDoc->GetNumberFormat( ScAddress( nCol, nRow, nDocTab ) ) );
+ nFormat = pFormatter->GetType( nNumFormat );
aString = aDocStr;
fValue = fVal;
mbFlag |= MK_VAL|MK_DATA;
- nNumFormat = pDoc->GetNumberFormat( ScAddress( nCol, nRow, nDocTab ) );
lcl_isDate( nFormat ) ? ( mbFlag |= MK_DATE ) : (mbFlag &= ~MK_DATE);
}
else if ( pDoc->HasData( nCol,nRow, nDocTab ) )
@@ -938,23 +938,28 @@ void ScDPTableDataCache::AddLabel(ScDPItemData *pData)
//reset name if needed
String strNewName = pData->aString;
- sal_Bool bFound = sal_False;
- long nIndex = 1;
- do
+
+ // #i116457# don't modify empty column titles
+ if ( strNewName.Len() )
{
- for ( long i= mrLabelNames.size()-1; i>=0; i-- )
+ sal_Bool bFound = sal_False;
+ long nIndex = 1;
+ do
{
- if( mrLabelNames[i]->aString == strNewName )
+ for ( long i= mrLabelNames.size()-1; i>=0; i-- )
{
- strNewName = pData->aString;
- strNewName += String::CreateFromInt32( nIndex );
- nIndex ++ ;
- bFound = sal_True;
+ if( mrLabelNames[i]->aString == strNewName )
+ {
+ strNewName = pData->aString;
+ strNewName += String::CreateFromInt32( nIndex );
+ nIndex ++ ;
+ bFound = sal_True;
+ }
}
+ bFound = !bFound;
}
- bFound = !bFound;
+ while ( !bFound );
}
- while ( !bFound );
pData->aString = strNewName;
mrLabelNames.push_back( pData );
@@ -1021,10 +1026,15 @@ sal_uLong ScDPTableDataCache::GetNumberFormat( long nDim ) const
{
if ( nDim >= mnColumnCount )
return 0;
- if ( mpTableDataValues[nDim].size()==0 )
- return 0;
- else
- return mpTableDataValues[nDim][0]->nNumFormat;
+
+ // #i113411# take the number format from the first value entry
+ size_t nSize = mpTableDataValues[nDim].size();
+ size_t nPos = 0;
+ while ( nPos < nSize && mpTableDataValues[nDim][nPos]->GetType() != SC_VALTYPE_VALUE )
+ ++nPos;
+ if ( nPos < nSize )
+ return mpTableDataValues[nDim][nPos]->nNumFormat;
+ return 0;
}
sal_Bool ScDPTableDataCache::IsDateDimension( long nDim ) const
diff --git a/sc/source/core/data/drwlayer.cxx b/sc/source/core/data/drwlayer.cxx
index 59abdcfd6b60..c3f8edbbc265 100644
--- a/sc/source/core/data/drwlayer.cxx
+++ b/sc/source/core/data/drwlayer.cxx
@@ -430,16 +430,20 @@ void ScDrawLayer::ScCopyPage( sal_uInt16 nOldPos, sal_uInt16 nNewPos, sal_Bool b
SdrObject* pOldObject = aIter.Next();
while (pOldObject)
{
- // #116235#
- SdrObject* pNewObject = pOldObject->Clone();
- //SdrObject* pNewObject = pOldObject->Clone( pNewPage, this );
- pNewObject->SetModel(this);
- pNewObject->SetPage(pNewPage);
-
- pNewObject->NbcMove(Size(0,0));
- pNewPage->InsertObject( pNewObject );
- if (bRecording)
- AddCalcUndo( new SdrUndoInsertObj( *pNewObject ) );
+ // #i112034# do not copy internal objects (detective) and note captions
+ if ( pOldObject->GetLayer() != SC_LAYER_INTERN && !IsNoteCaption( pOldObject ) )
+ {
+ // #116235#
+ SdrObject* pNewObject = pOldObject->Clone();
+ //SdrObject* pNewObject = pOldObject->Clone( pNewPage, this );
+ pNewObject->SetModel(this);
+ pNewObject->SetPage(pNewPage);
+
+ pNewObject->NbcMove(Size(0,0));
+ pNewPage->InsertObject( pNewObject );
+ if (bRecording)
+ AddCalcUndo( new SdrUndoInsertObj( *pNewObject ) );
+ }
pOldObject = aIter.Next();
}
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index 3b10e51355e8..83c5412d08c3 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -2,7 +2,7 @@
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
- * Copyright 2000, 2010 Oracle and/or its affiliates.
+ * Copyright 2000, 2011 Oracle and/or its affiliates.
*
* OpenOffice.org - a multi-platform office productivity suite
*
@@ -59,6 +59,7 @@
#include "sheetevents.hxx"
#include "globstr.hrc"
#include "segmenttree.hxx"
+#include "dbcolect.hxx"
#include <math.h>
@@ -2487,8 +2488,22 @@ sal_uLong ScTable::GetScaledRowHeight( SCROW nStartRow, SCROW nEndRow, double fS
{
if (nLastRow > nEndRow)
nLastRow = nEndRow;
- sal_uInt32 nThisHeight = mpRowHeights->getSumValue(nRow, nLastRow);
- nHeight += static_cast<sal_uLong>(nThisHeight * fScale);
+
+ // #i117315# can't use getSumValue, because individual values must be rounded
+ while (nRow <= nLastRow)
+ {
+ ScFlatUInt16RowSegments::RangeData aData;
+ if (!mpRowHeights->getRangeData(nRow, aData))
+ return nHeight; // shouldn't happen
+
+ SCROW nSegmentEnd = std::min( nLastRow, aData.mnRow2 );
+
+ // round-down a single height value, multiply resulting (pixel) values
+ sal_uLong nOneHeight = static_cast<sal_uLong>( aData.mnValue * fScale );
+ nHeight += nOneHeight * ( nSegmentEnd + 1 - nRow );
+
+ nRow = nSegmentEnd + 1;
+ }
}
nRow = nLastRow + 1;
}
@@ -2772,6 +2787,19 @@ void ScTable::ShowRows(SCROW nRow1, SCROW nRow2, bool bShow)
DecRecalcLevel();
}
+sal_Bool ScTable::IsDataFiltered() const
+{
+ sal_Bool bAnyQuery = sal_False;
+ ScDBData* pDBData = pDocument->GetFilterDBAtTable(nTab);
+ if ( pDBData )
+ {
+ ScQueryParam aParam;
+ pDBData->GetQueryParam( aParam );
+ if ( aParam.GetEntry(0).bDoQuery )
+ bAnyQuery = sal_True;
+ }
+ return bAnyQuery;
+}
void ScTable::SetColFlags( SCCOL nCol, sal_uInt8 nNewFlags )
{
diff --git a/sc/source/core/data/table4.cxx b/sc/source/core/data/table4.cxx
index 5c7c872f6c64..ba68fa53b13f 100644
--- a/sc/source/core/data/table4.cxx
+++ b/sc/source/core/data/table4.cxx
@@ -2,7 +2,7 @@
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
- * Copyright 2000, 2010 Oracle and/or its affiliates.
+ * Copyright 2000, 2011 Oracle and/or its affiliates.
*
* OpenOffice.org - a multi-platform office productivity suite
*
@@ -78,6 +78,7 @@
#include "rangenam.hxx"
#include "docpool.hxx"
#include "progress.hxx"
+#include "segmenttree.hxx"
#include <math.h>
@@ -198,7 +199,7 @@ void ScTable::FillAnalyse( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
rMinDigits = 0;
rListData = NULL;
rCmd = FILL_SIMPLE;
- if ( nScFillModeMouseModifier & KEY_MOD1 )
+ if (( nScFillModeMouseModifier & KEY_MOD1 )||IsDataFiltered()) //i89232
return ; // Ctrl-Taste: Copy
SCCOL nAddX;
@@ -567,11 +568,14 @@ void ScTable::FillAuto( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
sal_uLong nIMin = nIStart;
sal_uLong nIMax = nIEnd;
PutInOrder(nIMin,nIMax);
- if (bVertical)
- DeleteArea(nCol1, static_cast<SCROW>(nIMin), nCol2, static_cast<SCROW>(nIMax), IDF_AUTOFILL);
- else
- DeleteArea(static_cast<SCCOL>(nIMin), nRow1, static_cast<SCCOL>(nIMax), nRow2, IDF_AUTOFILL);
-
+ sal_Bool bHasFiltered = IsDataFiltered();
+ if (!bHasFiltered) //modify for i89232
+ {
+ if (bVertical)
+ DeleteArea(nCol1, static_cast<SCROW>(nIMin), nCol2, static_cast<SCROW>(nIMax), IDF_AUTOFILL);
+ else
+ DeleteArea(static_cast<SCCOL>(nIMin), nRow1, static_cast<SCCOL>(nIMax), nRow2, IDF_AUTOFILL);
+ }
sal_uLong nProgress = rProgress.GetState();
//
@@ -617,7 +621,7 @@ void ScTable::FillAuto( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
pNewPattern = NULL;
}
- if ( bVertical && nISrcStart == nISrcEnd )
+ if ( bVertical && nISrcStart == nISrcEnd && !bHasFiltered )
{
// Attribute komplett am Stueck setzen
if (pNewPattern || pSrcPattern != pDocument->GetDefPattern())
@@ -635,37 +639,44 @@ void ScTable::FillAuto( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
break; // Schleife abbrechen
}
- if ( pSrcPattern != aCol[nCol].GetPattern( static_cast<SCROW>(nRow) ) )
+ if ( !RowFiltered(nRow) )
{
- // Vorlage auch uebernehmen
- //! am AttrArray mit ApplyPattern zusammenfassen ??
- if ( pStyleSheet )
- aCol[nCol].ApplyStyle( static_cast<SCROW>(nRow), *pStyleSheet );
+ if ( bHasFiltered )
+ DeleteArea(static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow),
+ static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), IDF_AUTOFILL);
- // ApplyPattern statt SetPattern um alte MergeFlags stehenzulassen
- if ( pNewPattern )
- aCol[nCol].ApplyPattern( static_cast<SCROW>(nRow), *pNewPattern );
- else
- aCol[nCol].ApplyPattern( static_cast<SCROW>(nRow), *pSrcPattern );
- }
+ if ( pSrcPattern != aCol[nCol].GetPattern( static_cast<SCROW>(nRow) ) )
+ {
+ // Vorlage auch uebernehmen
+ //! am AttrArray mit ApplyPattern zusammenfassen ??
+ if ( pStyleSheet )
+ aCol[nCol].ApplyStyle( static_cast<SCROW>(nRow), *pStyleSheet );
- if (nAtSrc==nISrcEnd)
- {
- if ( nAtSrc != nISrcStart )
- { // mehr als eine Source-Zelle
- nAtSrc = nISrcStart;
+ // ApplyPattern statt SetPattern um alte MergeFlags stehenzulassen
+ if ( pNewPattern )
+ aCol[nCol].ApplyPattern( static_cast<SCROW>(nRow), *pNewPattern );
+ else
+ aCol[nCol].ApplyPattern( static_cast<SCROW>(nRow), *pSrcPattern );
+ }
+
+ if (nAtSrc==nISrcEnd)
+ {
+ if ( nAtSrc != nISrcStart )
+ { // mehr als eine Source-Zelle
+ nAtSrc = nISrcStart;
+ bGetPattern = sal_True;
+ }
+ }
+ else if (bPositive)
+ {
+ ++nAtSrc;
+ bGetPattern = sal_True;
+ }
+ else
+ {
+ --nAtSrc;
bGetPattern = sal_True;
}
- }
- else if (bPositive)
- {
- ++nAtSrc;
- bGetPattern = sal_True;
- }
- else
- {
- --nAtSrc;
- bGetPattern = sal_True;
}
if (rInner == nIEnd) break;
@@ -733,7 +744,7 @@ void ScTable::FillAuto( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
{
sal_uLong nSource = nISrcStart;
double nDelta;
- if ( nScFillModeMouseModifier & KEY_MOD1 )
+ if (( nScFillModeMouseModifier & KEY_MOD1 )||bHasFiltered) //i89232
nDelta = 0.0;
else if ( bPositive )
nDelta = 1.0;
@@ -750,6 +761,7 @@ void ScTable::FillAuto( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
ScBaseCell* pSrcCell = NULL;
CellType eCellType = CELLTYPE_NONE;
sal_Bool bIsOrdinalSuffix = sal_False;
+ sal_Bool bRowFiltered = sal_False; //i89232
rInner = nIStart;
while (true) // #i53728# with "for (;;)" old solaris/x86 compiler mis-optimizes
@@ -775,7 +787,7 @@ void ScTable::FillAuto( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
((ScStringCell*)pSrcCell)->GetString( aValue );
else
((ScEditCell*)pSrcCell)->GetString( aValue );
- if ( !(nScFillModeMouseModifier & KEY_MOD1) )
+ if ( !(nScFillModeMouseModifier & KEY_MOD1) && !bHasFiltered) //i89232
{
nCellDigits = 0; // look at each source cell individually
nHeadNoneTail = lcl_DecompValueString(
@@ -794,92 +806,101 @@ void ScTable::FillAuto( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
else
eCellType = CELLTYPE_NONE;
}
- switch (eCellType)
+
+ //Modify for i89232
+ bRowFiltered = mpFilteredRows->getValue(nRow);
+
+ if (!bRowFiltered)
{
- case CELLTYPE_VALUE:
- aCol[nCol].Insert(static_cast<SCROW>(nRow), new ScValueCell(nVal + nDelta));
- break;
- case CELLTYPE_STRING:
- case CELLTYPE_EDIT:
- if ( nHeadNoneTail )
- {
- // #i48009# with the "nStringValue+(long)nDelta" expression within the
- // lcl_ValueString calls, gcc 3.4.1 makes wrong optimizations (ok in 3.4.3),
- // so nNextValue is now calculated ahead.
- sal_Int32 nNextValue = nStringValue+(sal_Int32)nDelta;
+ //End of i89232
- String aStr;
- if ( nHeadNoneTail < 0 )
+ switch (eCellType)
+ {
+ case CELLTYPE_VALUE:
+ aCol[nCol].Insert(static_cast<SCROW>(nRow), new ScValueCell(nVal + nDelta));
+ break;
+ case CELLTYPE_STRING:
+ case CELLTYPE_EDIT:
+ if ( nHeadNoneTail )
{
- aCol[nCol].Insert( static_cast<SCROW>(nRow),
- lcl_getSuffixCell( pDocument,
- nNextValue, nCellDigits, aValue,
- eCellType, bIsOrdinalSuffix));
+ // #i48009# with the "nStringValue+(long)nDelta" expression within the
+ // lcl_ValueString calls, gcc 3.4.1 makes wrong optimizations (ok in 3.4.3),
+ // so nNextValue is now calculated ahead.
+ sal_Int32 nNextValue = nStringValue+(sal_Int32)nDelta;
+
+ String aStr;
+ if ( nHeadNoneTail < 0 )
+ {
+ aCol[nCol].Insert( static_cast<SCROW>(nRow),
+ lcl_getSuffixCell( pDocument,
+ nNextValue, nCellDigits, aValue,
+ eCellType, bIsOrdinalSuffix));
+ }
+ else
+ {
+ aStr = aValue;
+ aStr += lcl_ValueString( nNextValue, nCellDigits );
+ aCol[nCol].Insert( static_cast<SCROW>(nRow),
+ new ScStringCell( aStr));
+ }
}
else
{
- aStr = aValue;
- aStr += lcl_ValueString( nNextValue, nCellDigits );
- aCol[nCol].Insert( static_cast<SCROW>(nRow),
- new ScStringCell( aStr));
- }
- }
- else
- {
- ScAddress aDestPos( static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), nTab );
- switch ( eCellType )
- {
- case CELLTYPE_STRING:
- case CELLTYPE_EDIT:
- aCol[nCol].Insert( aDestPos.Row(), pSrcCell->CloneWithoutNote( *pDocument ) );
- break;
- default:
+ ScAddress aDestPos( static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), nTab );
+ switch ( eCellType )
{
- // added to avoid warnings
+ case CELLTYPE_STRING:
+ case CELLTYPE_EDIT:
+ aCol[nCol].Insert( aDestPos.Row(), pSrcCell->CloneWithoutNote( *pDocument ) );
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
}
}
+ break;
+ case CELLTYPE_FORMULA :
+ FillFormula( nFormulaCounter, bFirst,
+ (ScFormulaCell*) pSrcCell,
+ static_cast<SCCOL>(nCol),
+ static_cast<SCROW>(nRow), (rInner == nIEnd) );
+ if (nFormulaCounter - nActFormCnt > nMaxFormCnt)
+ nMaxFormCnt = nFormulaCounter - nActFormCnt;
+ break;
+ default:
+ {
+ // added to avoid warnings
}
- break;
- case CELLTYPE_FORMULA :
- FillFormula( nFormulaCounter, bFirst,
- (ScFormulaCell*) pSrcCell,
- static_cast<SCCOL>(nCol),
- static_cast<SCROW>(nRow), (rInner == nIEnd) );
- if (nFormulaCounter - nActFormCnt > nMaxFormCnt)
- nMaxFormCnt = nFormulaCounter - nActFormCnt;
- break;
- default:
- {
- // added to avoid warnings
}
- }
- if (nSource==nISrcEnd)
- {
- if ( nSource != nISrcStart )
- { // mehr als eine Source-Zelle
- nSource = nISrcStart;
+ if (nSource==nISrcEnd)
+ {
+ if ( nSource != nISrcStart )
+ { // mehr als eine Source-Zelle
+ nSource = nISrcStart;
+ bGetCell = sal_True;
+ }
+ if ( !(nScFillModeMouseModifier & KEY_MOD1) && !bHasFiltered ) //i89232
+ {
+ if ( bPositive )
+ nDelta += 1.0;
+ else
+ nDelta -= 1.0;
+ }
+ nFormulaCounter = nActFormCnt;
+ bFirst = sal_False;
+ }
+ else if (bPositive)
+ {
+ ++nSource;
bGetCell = sal_True;
}
- if ( !(nScFillModeMouseModifier & KEY_MOD1) )
+ else
{
- if ( bPositive )
- nDelta += 1.0;
- else
- nDelta -= 1.0;
+ --nSource;
+ bGetCell = sal_True;
}
- nFormulaCounter = nActFormCnt;
- bFirst = sal_False;
- }
- else if (bPositive)
- {
- ++nSource;
- bGetCell = sal_True;
- }
- else
- {
- --nSource;
- bGetCell = sal_True;
}
// Progress in der inneren Schleife nur bei teuren Zellen,
@@ -978,6 +999,30 @@ String ScTable::GetAutoFillPreview( const ScRange& rSource, SCCOL nEndX, SCROW n
}
else if ( eFillCmd == FILL_SIMPLE ) // Auffuellen mit Muster
{
+ //Add for i89232
+ if ((eFillDir == FILL_TO_BOTTOM)||(eFillDir == FILL_TO_TOP))
+ {
+ long nBegin = 0;
+ long nEnd = 0;
+ if (nEndY > nRow1)
+ {
+ nBegin = nRow2+1;
+ nEnd = nEndY;
+ }
+ else
+ {
+ nBegin = nEndY;
+ nEnd = nRow1 -1;
+ }
+ long nNonFiltered = CountNonFilteredRows(nBegin, nEnd);
+ long nFiltered = nEnd + 1 - nBegin - nNonFiltered;
+ if (nIndex >0)
+ nIndex = nIndex - nFiltered;
+ else
+ nIndex = nIndex + nFiltered;
+ }
+ //End of i89232
+
long nPosIndex = nIndex;
while ( nPosIndex < 0 )
nPosIndex += nSrcCount;
@@ -1008,7 +1053,7 @@ String ScTable::GetAutoFillPreview( const ScRange& rSource, SCCOL nEndX, SCROW n
((ScStringCell*)pCell)->GetString( aValue );
else
((ScEditCell*)pCell)->GetString( aValue );
- if ( !(nScFillModeMouseModifier & KEY_MOD1) )
+ if ( !(nScFillModeMouseModifier & KEY_MOD1) && !IsDataFiltered() ) //i89232
{
sal_Int32 nVal;
sal_uInt16 nCellDigits = 0; // look at each source cell individually
@@ -1029,7 +1074,7 @@ String ScTable::GetAutoFillPreview( const ScRange& rSource, SCCOL nEndX, SCROW n
{
// dabei kann's keinen Ueberlauf geben...
double nVal = ((ScValueCell*)pCell)->GetValue();
- if ( !(nScFillModeMouseModifier & KEY_MOD1) )
+ if ( !(nScFillModeMouseModifier & KEY_MOD1) && !IsDataFiltered() ) //i89232
nVal += (double) nDelta;
Color* pColor;
diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx
index 0ab37d167b01..0adef9f88348 100644
--- a/sc/source/core/inc/interpre.hxx
+++ b/sc/source/core/inc/interpre.hxx
@@ -696,6 +696,7 @@ double GetGamma(double x);
double GetLogGamma(double x);
double GetBeta(double fAlpha, double fBeta);
double GetLogBeta(double fAlpha, double fBeta);
+double GetBinomDistPMF(double x, double n, double p); //probability mass function
void ScLogGamma();
void ScGamma();
void ScPhi();
diff --git a/sc/source/core/tool/address.cxx b/sc/source/core/tool/address.cxx
index 26a194b731ef..e24a4ff4158e 100644
--- a/sc/source/core/tool/address.cxx
+++ b/sc/source/core/tool/address.cxx
@@ -1648,8 +1648,8 @@ void ScAddress::Format( String& r, sal_uInt16 nFlags, ScDocument* pDoc,
// External Reference, same as in ScCompiler::MakeTabStr()
if( aTabName.GetChar(0) == '\'' )
{ // "'Doc'#Tab"
- xub_StrLen nPos = ScGlobal::FindUnquoted( aTabName, SC_COMPILER_FILE_TAB_SEP);
- if (nPos != STRING_NOTFOUND && nPos > 0 && aTabName.GetChar(nPos-1) == '\'')
+ xub_StrLen nPos = ScCompiler::GetDocTabPos( aTabName);
+ if (nPos != STRING_NOTFOUND)
{
aDocName = aTabName.Copy( 0, nPos + 1 );
aTabName.Erase( 0, nPos + 1 );
@@ -1731,8 +1731,8 @@ lcl_Split_DocTab( const ScDocument* pDoc, SCTAB nTab,
// External reference, same as in ScCompiler::MakeTabStr()
if ( rTabName.GetChar(0) == '\'' )
{ // "'Doc'#Tab"
- xub_StrLen nPos = ScGlobal::FindUnquoted( rTabName, SC_COMPILER_FILE_TAB_SEP);
- if (nPos != STRING_NOTFOUND && nPos > 0 && rTabName.GetChar(nPos-1) == '\'')
+ xub_StrLen nPos = ScCompiler::GetDocTabPos( rTabName);
+ if (nPos != STRING_NOTFOUND)
{
rDocName = rTabName.Copy( 0, nPos + 1 );
rTabName.Erase( 0, nPos + 1 );
diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index 3dd25801532f..31964eff34be 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -855,18 +855,14 @@ struct ConventionOOO_A1 : public Convention_A1
aString = ScGlobal::GetRscString(STR_NO_REF_TABLE);
else
{
- if ( aString.GetChar(0) == '\'' )
- { // "'Doc'#Tab"
- xub_StrLen nPos = ScGlobal::FindUnquoted( aString, SC_COMPILER_FILE_TAB_SEP);
- if (nPos != STRING_NOTFOUND && nPos > 0 && aString.GetChar(nPos-1) == '\'')
- {
- aDoc = aString.Copy( 0, nPos + 1 );
- aString.Erase( 0, nPos + 1 );
- aDoc = INetURLObject::decode( aDoc, INET_HEX_ESCAPE,
+ // "'Doc'#Tab"
+ xub_StrLen nPos = ScCompiler::GetDocTabPos( aString);
+ if (nPos != STRING_NOTFOUND)
+ {
+ aDoc = aString.Copy( 0, nPos + 1 );
+ aString.Erase( 0, nPos + 1 );
+ aDoc = INetURLObject::decode( aDoc, INET_HEX_ESCAPE,
INetURLObject::DECODE_UNAMBIGUOUS );
- }
- else
- aDoc.Erase();
}
else
aDoc.Erase();
@@ -1203,18 +1199,15 @@ struct ConventionXL
}
// Cheesy hack to unparse the OOO style "'Doc'#Tab"
- if ( rTabName.GetChar(0) == '\'' )
+ xub_StrLen nPos = ScCompiler::GetDocTabPos( rTabName);
+ if (nPos != STRING_NOTFOUND)
{
- xub_StrLen nPos = ScGlobal::FindUnquoted( rTabName, SC_COMPILER_FILE_TAB_SEP);
- if (nPos != STRING_NOTFOUND && nPos > 0 && rTabName.GetChar(nPos-1) == '\'')
- {
- rDocName = rTabName.Copy( 0, nPos );
- // TODO : More research into how XL escapes the doc path
- rDocName = INetURLObject::decode( rDocName, INET_HEX_ESCAPE,
+ rDocName = rTabName.Copy( 0, nPos );
+ // TODO : More research into how XL escapes the doc path
+ rDocName = INetURLObject::decode( rDocName, INET_HEX_ESCAPE,
INetURLObject::DECODE_UNAMBIGUOUS );
- rTabName.Erase( 0, nPos + 1 );
- bHasDoc = true;
- }
+ rTabName.Erase( 0, nPos + 1 );
+ bHasDoc = true;
}
// XL uses the same sheet name quoting conventions in both modes
@@ -1872,6 +1865,18 @@ void ScCompiler::CheckTabQuotes( String& rString,
}
}
+
+xub_StrLen ScCompiler::GetDocTabPos( const String& rString )
+{
+ if (rString.GetChar(0) != '\'')
+ return STRING_NOTFOUND;
+ xub_StrLen nPos = ScGlobal::FindUnquoted( rString, SC_COMPILER_FILE_TAB_SEP);
+ // it must be 'Doc'#
+ if (nPos != STRING_NOTFOUND && rString.GetChar(nPos-1) != '\'')
+ nPos = STRING_NOTFOUND;
+ return nPos;
+}
+
//---------------------------------------------------------------------------
void ScCompiler::SetRefConvention( FormulaGrammar::AddressConvention eConv )
diff --git a/sc/source/core/tool/dbcolect.cxx b/sc/source/core/tool/dbcolect.cxx
index 800716bef3b6..baf2c3de8c2a 100644
--- a/sc/source/core/tool/dbcolect.cxx
+++ b/sc/source/core/tool/dbcolect.cxx
@@ -2,7 +2,7 @@
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
- * Copyright 2000, 2010 Oracle and/or its affiliates.
+ * Copyright 2000, 2011 Oracle and/or its affiliates.
*
* OpenOffice.org - a multi-platform office productivity suite
*
@@ -753,6 +753,27 @@ ScDBData* ScDBCollection::GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCO
return pNoNameData; // "unbenannt" nur zurueck, wenn sonst nichts gefunden
}
+ScDBData* ScDBCollection::GetFilterDBAtTable(SCTAB nTab) const
+{
+ ScDBData* pDataEmpty = NULL;
+ if (pItems)
+ {
+ for (sal_uInt16 i = 0; i < nCount; i++)
+ {
+ ScDBData* pDBTemp = (ScDBData*)pItems[i];
+ if ( pDBTemp->nTable == nTab )
+ {
+ sal_Bool bFilter = pDBTemp->HasAutoFilter() || pDBTemp->HasQueryParam();
+
+ if ( bFilter )
+ return pDBTemp;
+ }
+ }
+ }
+
+ return pDataEmpty;
+}
+
sal_Bool ScDBCollection::SearchName( const String& rName, sal_uInt16& rIndex ) const
{
ScDBData aDataObj( rName, 0,0,0,0,0 );
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index 7e015e12d16e..c507c3970bb1 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -653,6 +653,7 @@ double ScInterpreter::CompareFunc( const ScCompare& rComp, ScCompareOptions* pOp
if ( !rComp.bEmpty[1] && rComp.bVal[1] && !::rtl::math::isFinite( rComp.nVal[1]))
return rComp.nVal[1];
+ size_t nStringQuery = 0; // 0:=no, 1:=0, 2:=1
double fRes = 0;
if ( rComp.bEmpty[ 0 ] )
{
@@ -709,16 +710,22 @@ double ScInterpreter::CompareFunc( const ScCompare& rComp, ScCompareOptions* pOp
}
}
else
- fRes = -1; // number is less than string
+ {
+ fRes = -1; // number is less than string
+ nStringQuery = 2; // 1+1
+ }
}
else if( rComp.bVal[ 1 ] )
- fRes = 1; // number is less than string
+ {
+ fRes = 1; // string is greater than number
+ nStringQuery = 1; // 0+1
+ }
else
{
// Both strings.
if (pOptions)
{
- // All similar to Sctable::ValidQuery(), *rComp.pVal[1] actually
+ // All similar to ScTable::ValidQuery(), *rComp.pVal[1] actually
// is/must be identical to *rEntry.pStr, which is essential for
// regex to work through GetSearchTextPtr().
ScQueryEntry& rEntry = pOptions->aQueryEntry;
@@ -768,6 +775,20 @@ double ScInterpreter::CompareFunc( const ScCompare& rComp, ScCompareOptions* pOp
fRes = (double) ScGlobal::GetCaseCollator()->compareString(
*rComp.pVal[ 0 ], *rComp.pVal[ 1 ] );
}
+ if (nStringQuery && pOptions)
+ {
+ const ScQueryEntry& rEntry = pOptions->aQueryEntry;
+ if (!rEntry.bQueryByString && rEntry.pStr->Len() &&
+ (rEntry.eOp == SC_EQUAL || rEntry.eOp == SC_NOT_EQUAL))
+ {
+ // As in ScTable::ValidQuery() match a numeric string for a
+ // number query that originated from a string, e.g. in SUMIF
+ // and COUNTIF. Transliteration is not needed here.
+ bool bEqual = rComp.pVal[nStringQuery-1]->Equals( *rEntry.pStr);
+ // match => fRes=0, else fRes=1
+ fRes = (rEntry.eOp == SC_NOT_EQUAL) ? bEqual : !bEqual;
+ }
+ }
return fRes;
}
@@ -6223,7 +6244,7 @@ void ScInterpreter::ScDBVarP()
}
-ScTokenArray* lcl_CreateExternalRefTokenArray( const ScAddress& rPos, ScDocument* pDoc,
+FormulaSubroutineToken* lcl_CreateExternalRefSubroutine( const ScAddress& rPos, ScDocument* pDoc,
const ScAddress::ExternalInfo& rExtInfo, const ScRefAddress& rRefAd1,
const ScRefAddress* pRefAd2 )
{
@@ -6265,7 +6286,7 @@ ScTokenArray* lcl_CreateExternalRefTokenArray( const ScAddress& rPos, ScDocument
rExtInfo.maTabName, nSheets);
ScCompiler aComp( pDoc, rPos, *pTokenArray);
aComp.CompileTokenArray();
- return pTokenArray;
+ return new FormulaSubroutineToken( pTokenArray);
}
@@ -6294,15 +6315,10 @@ void ScInterpreter::ScIndirect()
{
if (aExtInfo.mbExternal)
{
- /* TODO: future versions should implement a proper subroutine
- * token. This procedure here is a minimally invasive fix for
- * #i101645# in OOo3.1.1 */
- // Push a subroutine on the instruction code stack that
- // resolves the external reference as the next instruction.
- aCode.Push( lcl_CreateExternalRefTokenArray( aPos, pDok,
+ // Push a subroutine that resolves the external reference as
+ // the next instruction.
+ PushTempToken( lcl_CreateExternalRefSubroutine( aPos, pDok,
aExtInfo, aRefAd, &aRefAd2));
- // Signal subroutine call to interpreter.
- PushTempToken( new FormulaUnknownToken( ocCall));
}
else
PushDoubleRef( aRefAd.Col(), aRefAd.Row(), aRefAd.Tab(),
@@ -6314,15 +6330,10 @@ void ScInterpreter::ScIndirect()
{
if (aExtInfo.mbExternal)
{
- /* TODO: future versions should implement a proper subroutine
- * token. This procedure here is a minimally invasive fix for
- * #i101645# in OOo3.1.1 */
- // Push a subroutine on the instruction code stack that
- // resolves the external reference as the next instruction.
- aCode.Push( lcl_CreateExternalRefTokenArray( aPos, pDok,
+ // Push a subroutine that resolves the external reference as
+ // the next instruction.
+ PushTempToken( lcl_CreateExternalRefSubroutine( aPos, pDok,
aExtInfo, aRefAd, NULL));
- // Signal subroutine call to interpreter.
- PushTempToken( new FormulaUnknownToken( ocCall));
}
else
PushSingleRef( aRefAd.Col(), aRefAd.Row(), aRefAd.Tab() );
@@ -6441,9 +6452,27 @@ void ScInterpreter::ScAddressFunc()
const ScAddress aAdr( nCol, nRow, 0);
aAdr.Format( aRefStr, nFlags, pDok, aDetails );
- if( nParamCount >= 5 )
+ if( nParamCount >= 5 && sTabStr.Len() )
{
- ScCompiler::CheckTabQuotes( sTabStr, eConv);
+ String aDoc;
+ if (eConv == FormulaGrammar::CONV_OOO)
+ {
+ // Isolate Tab from 'Doc'#Tab
+ xub_StrLen nPos = ScCompiler::GetDocTabPos( sTabStr);
+ if (nPos != STRING_NOTFOUND)
+ {
+ if (sTabStr.GetChar(nPos+1) == '$')
+ ++nPos; // also split 'Doc'#$Tab
+ aDoc = sTabStr.Copy( 0, nPos+1);
+ sTabStr.Erase( 0, nPos+1);
+ }
+ }
+ /* TODO: yet unsupported external reference in CONV_XL_R1C1 syntax may
+ * need some extra handling to isolate Tab from Doc. */
+ if (sTabStr.GetChar(0) != '\'' || sTabStr.GetChar(sTabStr.Len()-1) != '\'')
+ ScCompiler::CheckTabQuotes( sTabStr, eConv);
+ if (aDoc.Len())
+ sTabStr.Insert( aDoc, 0);
sTabStr += static_cast<sal_Unicode>(eConv == FormulaGrammar::CONV_XL_R1C1 ? '!' : '.');
sTabStr += aRefStr;
PushString( sTabStr );
@@ -6453,6 +6482,24 @@ void ScInterpreter::ScAddressFunc()
}
+FormulaSubroutineToken* lcl_CreateExternalRefSubroutine( const ScAddress& rPos,
+ ScDocument* pDoc, const FormulaTokenRef& xExtRef )
+{
+ // The exact usage (which cell range) of the external table can't be
+ // detected during the store-to-file cycle, mark it as permanently
+ // referenced so it gets stored even if not directly referenced anywhere.
+ ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
+ pRefMgr->setCacheTableReferencedPermanently(
+ static_cast<const ScToken*>(xExtRef.get())->GetIndex(),
+ static_cast<const ScToken*>(xExtRef.get())->GetString(), 1);
+ ScTokenArray* pTokenArray = new ScTokenArray;
+ pTokenArray->AddToken( *xExtRef);
+ ScCompiler aComp( pDoc, rPos, *pTokenArray);
+ aComp.CompileTokenArray();
+ return new FormulaSubroutineToken( pTokenArray);
+}
+
+
void ScInterpreter::ScOffset()
{
RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScOffset" );
@@ -6477,54 +6524,129 @@ void ScInterpreter::ScOffset()
PushIllegalArgument();
return;
}
- if (GetStackType() == svSingleRef)
- {
- PopSingleRef(nCol1, nRow1, nTab1);
- if (nParamCount == 3 || (nColNew < 0 && nRowNew < 0))
- {
- nCol1 = (SCCOL)((long) nCol1 + nColPlus);
- nRow1 = (SCROW)((long) nRow1 + nRowPlus);
- if (!ValidCol(nCol1) || !ValidRow(nRow1))
- PushIllegalArgument();
- else
- PushSingleRef(nCol1, nRow1, nTab1);
- }
- else
- {
- if (nColNew < 0)
- nColNew = 1;
- if (nRowNew < 0)
- nRowNew = 1;
- nCol1 = (SCCOL)((long)nCol1+nColPlus); // ! nCol1 wird veraendert!
- nRow1 = (SCROW)((long)nRow1+nRowPlus);
- nCol2 = (SCCOL)((long)nCol1+nColNew-1);
- nRow2 = (SCROW)((long)nRow1+nRowNew-1);
- if (!ValidCol(nCol1) || !ValidRow(nRow1) ||
- !ValidCol(nCol2) || !ValidRow(nRow2))
- PushIllegalArgument();
- else
- PushDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab1);
- }
- }
- else if (GetStackType() == svDoubleRef)
+ FormulaTokenRef xExtRef;
+ switch (GetStackType())
{
- PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
- if (nColNew < 0)
- nColNew = nCol2 - nCol1 + 1;
- if (nRowNew < 0)
- nRowNew = nRow2 - nRow1 + 1;
- nCol1 = (SCCOL)((long)nCol1+nColPlus);
- nRow1 = (SCROW)((long)nRow1+nRowPlus);
- nCol2 = (SCCOL)((long)nCol1+nColNew-1);
- nRow2 = (SCROW)((long)nRow1+nRowNew-1);
- if (!ValidCol(nCol1) || !ValidRow(nRow1) ||
- !ValidCol(nCol2) || !ValidRow(nRow2) || nTab1 != nTab2)
- PushIllegalArgument();
- else
- PushDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab1);
+ case svExternalSingleRef:
+ xExtRef = PopToken()->Clone();
+ // fallthru
+ case svSingleRef:
+ {
+ if (xExtRef)
+ {
+ ScSingleRefData& rData = static_cast<ScToken*>(xExtRef.get())->GetSingleRef();
+ rData.CalcAbsIfRel( aPos);
+ nCol1 = rData.nCol;
+ nRow1 = rData.nRow;
+ nTab1 = rData.nTab;
+ }
+ else
+ PopSingleRef( nCol1, nRow1, nTab1);
+ if (nParamCount == 3 || (nColNew < 0 && nRowNew < 0))
+ {
+ nCol1 = (SCCOL)((long) nCol1 + nColPlus);
+ nRow1 = (SCROW)((long) nRow1 + nRowPlus);
+ if (!ValidCol(nCol1) || !ValidRow(nRow1))
+ PushIllegalArgument();
+ else if (xExtRef)
+ {
+ ScSingleRefData& rData = static_cast<ScToken*>(xExtRef.get())->GetSingleRef();
+ rData.nCol = nCol1;
+ rData.nRow = nRow1;
+ rData.nTab = nTab1;
+ rData.CalcRelFromAbs( aPos);
+ // Push a subroutine that resolves the external
+ // reference as the next instruction.
+ PushTempToken( lcl_CreateExternalRefSubroutine( aPos, pDok, xExtRef));
+ }
+ else
+ PushSingleRef(nCol1, nRow1, nTab1);
+ }
+ else
+ {
+ if (nColNew < 0)
+ nColNew = 1;
+ if (nRowNew < 0)
+ nRowNew = 1;
+ nCol1 = (SCCOL)((long)nCol1+nColPlus); // ! nCol1 is modified
+ nRow1 = (SCROW)((long)nRow1+nRowPlus);
+ nCol2 = (SCCOL)((long)nCol1+nColNew-1);
+ nRow2 = (SCROW)((long)nRow1+nRowNew-1);
+ if (!ValidCol(nCol1) || !ValidRow(nRow1) ||
+ !ValidCol(nCol2) || !ValidRow(nRow2))
+ PushIllegalArgument();
+ else if (xExtRef)
+ {
+ // Convert SingleRef to DoubleRef.
+ xExtRef = new ScExternalDoubleRefToken(
+ *static_cast<const ScExternalSingleRefToken*>(xExtRef.get()));
+ ScComplexRefData& rData = static_cast<ScToken*>(xExtRef.get())->GetDoubleRef();
+ rData.Ref1.nCol = nCol1;
+ rData.Ref1.nRow = nRow1;
+ rData.Ref1.nTab = nTab1;
+ rData.Ref2.nCol = nCol2;
+ rData.Ref2.nRow = nRow2;
+ rData.Ref2.nTab = nTab1;
+ rData.CalcRelFromAbs( aPos);
+ // Push a subroutine that resolves the external
+ // reference as the next instruction.
+ PushTempToken( lcl_CreateExternalRefSubroutine( aPos, pDok, xExtRef));
+ }
+ else
+ PushDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab1);
+ }
+ }
+ break;
+ case svExternalDoubleRef:
+ xExtRef = PopToken()->Clone();
+ // fallthru
+ case svDoubleRef:
+ {
+ if (xExtRef)
+ {
+ ScComplexRefData& rData = static_cast<ScToken*>(xExtRef.get())->GetDoubleRef();
+ rData.CalcAbsIfRel( aPos);
+ nCol1 = rData.Ref1.nCol;
+ nRow1 = rData.Ref1.nRow;
+ nTab1 = rData.Ref1.nTab;
+ nCol2 = rData.Ref2.nCol;
+ nRow2 = rData.Ref2.nRow;
+ nTab2 = rData.Ref2.nTab;
+ }
+ else
+ PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
+ if (nColNew < 0)
+ nColNew = nCol2 - nCol1 + 1;
+ if (nRowNew < 0)
+ nRowNew = nRow2 - nRow1 + 1;
+ nCol1 = (SCCOL)((long)nCol1+nColPlus);
+ nRow1 = (SCROW)((long)nRow1+nRowPlus);
+ nCol2 = (SCCOL)((long)nCol1+nColNew-1);
+ nRow2 = (SCROW)((long)nRow1+nRowNew-1);
+ if (!ValidCol(nCol1) || !ValidRow(nRow1) ||
+ !ValidCol(nCol2) || !ValidRow(nRow2) || nTab1 != nTab2)
+ PushIllegalArgument();
+ else if (xExtRef)
+ {
+ ScComplexRefData& rData = static_cast<ScToken*>(xExtRef.get())->GetDoubleRef();
+ rData.Ref1.nCol = nCol1;
+ rData.Ref1.nRow = nRow1;
+ rData.Ref1.nTab = nTab1;
+ rData.Ref2.nCol = nCol2;
+ rData.Ref2.nRow = nRow2;
+ rData.Ref2.nTab = nTab1;
+ rData.CalcRelFromAbs( aPos);
+ // Push a subroutine that resolves the external
+ // reference as the next instruction.
+ PushTempToken( lcl_CreateExternalRefSubroutine( aPos, pDok, xExtRef));
+ }
+ else
+ PushDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab1);
+ }
+ break;
+ default:
+ PushIllegalParameter();
}
- else
- PushIllegalParameter();
}
}
diff --git a/sc/source/core/tool/interpr3.cxx b/sc/source/core/tool/interpr3.cxx
index dfcce4c06c3f..ef1a18b65def 100644
--- a/sc/source/core/tool/interpr3.cxx
+++ b/sc/source/core/tool/interpr3.cxx
@@ -949,17 +949,18 @@ double ScInterpreter::GetBetaDistPDF(double fX, double fA, double fB)
const double fLogDblMin = log( ::std::numeric_limits<double>::min());
double fLogY = (fX < 0.1) ? ::rtl::math::log1p(-fX) : log(0.5-fX+0.5);
double fLogX = log(fX);
- double fAm1 = fA-1.0;
- double fBm1 = fB-1.0;
+ double fAm1LogX = (fA-1.0) * fLogX;
+ double fBm1LogY = (fB-1.0) * fLogY;
double fLogBeta = GetLogBeta(fA,fB);
// check whether parts over- or underflow
- if ( fAm1 * fLogX < fLogDblMax && fAm1 * fLogX > fLogDblMin
- && fBm1 * fLogY < fLogDblMax && fBm1* fLogY > fLogDblMin
- && fLogBeta < fLogDblMax && fLogBeta > fLogDblMin )
+ if ( fAm1LogX < fLogDblMax && fAm1LogX > fLogDblMin
+ && fBm1LogY < fLogDblMax && fBm1LogY > fLogDblMin
+ && fLogBeta < fLogDblMax && fLogBeta > fLogDblMin
+ && fAm1LogX + fBm1LogY < fLogDblMax && fAm1LogX + fBm1LogY > fLogDblMin)
return pow(fX,fA-1.0) * pow(0.5-fX+0.5,fB-1.0) / GetBeta(fA,fB);
else // need logarithm;
// might overflow as a whole, but seldom, not worth to pre-detect it
- return exp((fA-1.0)*fLogX + (fB-1.0)* fLogY - fLogBeta);
+ return exp( fAm1LogX + fBm1LogY - fLogBeta);
}
@@ -1226,121 +1227,106 @@ void ScInterpreter::ScVariationen2()
}
}
-void ScInterpreter::ScB()
-{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScB" );
- sal_uInt8 nParamCount = GetByte();
- if ( !MustHaveParamCount( nParamCount, 3, 4 ) )
- return ;
- if (nParamCount == 3)
- {
- double x = ::rtl::math::approxFloor(GetDouble());
- double p = GetDouble();
- double n = ::rtl::math::approxFloor(GetDouble());
- if (n < 0.0 || x < 0.0 || x > n || p < 0.0 || p > 1.0)
- PushIllegalArgument();
- else
+
+double ScInterpreter::GetBinomDistPMF(double x, double n, double p)
+// used in ScB and ScBinomDist
+// preconditions: 0.0 <= x <= n, 0.0 < p < 1.0; x,n integral although double
{
- double q = 1.0 - p;
+ double q = (0.5 - p) + 0.5;
double fFactor = pow(q, n);
- if (fFactor == 0.0)
+ if (fFactor <=::std::numeric_limits<double>::min())
{
fFactor = pow(p, n);
- if (fFactor == 0.0)
- PushNoValue();
+ if (fFactor <= ::std::numeric_limits<double>::min())
+ return GetBetaDistPDF(p, x+1.0, n-x+1.0)/(n+1.0);
else
{
- sal_uLong max = (sal_uLong) (n - x);
- for (sal_uLong i = 0; i < max && fFactor > 0.0; i++)
+ sal_uInt32 max = static_cast<sal_uInt32>(n - x);
+ for (sal_uInt32 i = 0; i < max && fFactor > 0.0; i++)
fFactor *= (n-i)/(i+1)*q/p;
- PushDouble(fFactor);
+ return fFactor;
}
}
else
{
- sal_uLong max = (sal_uLong) x;
- for (sal_uLong i = 0; i < max && fFactor > 0.0; i++)
+ sal_uInt32 max = static_cast<sal_uInt32>(x);
+ for (sal_uInt32 i = 0; i < max && fFactor > 0.0; i++)
fFactor *= (n-i)/(i+1)*p/q;
- PushDouble(fFactor);
- }
+ return fFactor;
}
}
- else if (nParamCount == 4)
- {
- double xe = GetDouble();
- double xs = GetDouble();
- double p = GetDouble();
- double n = GetDouble();
-// alter Stand 300-SC
-// if ((xs < n) && (xe < n) && (p < 1.0))
-// {
-// double Varianz = sqrt(n * p * (1.0 - p));
-// xs = fabs(xs - (n * p /* / 2.0 STE */ ));
-// xe = fabs(xe - (n * p /* / 2.0 STE */ ));
-//// STE double nVal = gauss((xs + 0.5) / Varianz) + gauss((xe + 0.5) / Varianz);
-// double nVal = fabs(gauss(xs / Varianz) - gauss(xe / Varianz));
-// PushDouble(nVal);
-// }
- bool bIsValidX = ( 0.0 <= xs && xs <= xe && xe <= n);
- if ( bIsValidX && 0.0 < p && p < 1.0 )
- {
- double q = 1.0 - p;
- double fFactor = pow(q, n);
- if (fFactor == 0.0)
- {
- fFactor = pow(p, n);
- if (fFactor == 0.0)
- PushNoValue();
- else
+
+double lcl_GetBinomDistRange(double n, double xs,double xe,
+ double fFactor /* q^n */, double p, double q)
+//preconditions: 0.0 <= xs < xe <= n; xs,xe,n integral although double
{
- double fSum = 0.0;
- sal_uLong max;
- if (xe < (sal_uLong) n)
- max = (sal_uLong) (n-xe)-1;
- else
- max = 0;
- sal_uLong i;
- for (i = 0; i < max && fFactor > 0.0; i++)
- fFactor *= (n-i)/(i+1)*q/p;
- if (xs < (sal_uLong) n)
- max = (sal_uLong) (n-xs);
- else
- fSum = fFactor;
- for (; i < max && fFactor > 0.0; i++)
+ sal_uInt32 i;
+ double fSum;
+ // skip summands index 0 to xs-1, start sum with index xs
+ sal_uInt32 nXs = static_cast<sal_uInt32>( xs );
+ for (i = 1; i <= nXs && fFactor > 0.0; i++)
+ fFactor *= (n-i+1)/i * p/q;
+ fSum = fFactor; // Summand xs
+ sal_uInt32 nXe = static_cast<sal_uInt32>(xe);
+ for (i = nXs+1; i <= nXe && fFactor > 0.0; i++)
{
- fFactor *= (n-i)/(i+1)*q/p;
+ fFactor *= (n-i+1)/i * p/q;
fSum += fFactor;
}
- PushDouble(fSum);
+ return (fSum>1.0) ? 1.0 : fSum;
}
+
+void ScInterpreter::ScB()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScB" );
+ sal_uInt8 nParamCount = GetByte();
+ if ( !MustHaveParamCount( nParamCount, 3, 4 ) )
+ return ;
+ if (nParamCount == 3) // mass function
+ {
+ double x = ::rtl::math::approxFloor(GetDouble());
+ double p = GetDouble();
+ double n = ::rtl::math::approxFloor(GetDouble());
+ if (n < 0.0 || x < 0.0 || x > n || p < 0.0 || p > 1.0)
+ PushIllegalArgument();
+ else
+ if (p == 0.0)
+ PushDouble( (x == 0.0) ? 1.0 : 0.0 );
+ else
+ if ( p == 1.0)
+ PushDouble( (x == n) ? 1.0 : 0.0);
+ else
+ PushDouble(GetBinomDistPMF(x,n,p));
}
else
+ { // nParamCount == 4
+ double xe = ::rtl::math::approxFloor(GetDouble());
+ double xs = ::rtl::math::approxFloor(GetDouble());
+ double p = GetDouble();
+ double n = ::rtl::math::approxFloor(GetDouble());
+ double q = (0.5 - p) + 0.5;
+ bool bIsValidX = ( 0.0 <= xs && xs <= xe && xe <= n);
+ if ( bIsValidX && 0.0 < p && p < 1.0)
{
- sal_uLong max;
- double fSum;
- if ( (sal_uLong) xs == 0)
+ if (xs == xe) // mass function
+ PushDouble(GetBinomDistPMF(xs,n,p));
+ else
{
- fSum = fFactor;
- max = 0;
- }
+ double fFactor = pow(q, n);
+ if (fFactor > ::std::numeric_limits<double>::min())
+ PushDouble(lcl_GetBinomDistRange(n,xs,xe,fFactor,p,q));
else
{
- max = (sal_uLong) xs-1;
- fSum = 0.0;
+ fFactor = pow(p, n);
+ if (fFactor > ::std::numeric_limits<double>::min())
+ {
+ // sum from j=xs to xe {(n choose j) * p^j * q^(n-j)}
+ // = sum from i = n-xe to n-xs { (n choose i) * q^i * p^(n-i)}
+ PushDouble(lcl_GetBinomDistRange(n,n-xe,n-xs,fFactor,q,p));
}
- sal_uLong i;
- for (i = 0; i < max && fFactor > 0.0; i++)
- fFactor *= (n-i)/(i+1)*p/q;
- if ((sal_uLong)xe == 0) // beide 0
- fSum = fFactor;
else
- max = (sal_uLong) xe;
- for (; i < max && fFactor > 0.0; i++)
- {
- fFactor *= (n-i)/(i+1)*p/q;
- fSum += fFactor;
+ PushDouble(GetBetaDist(q,n-xe,xe+1.0)-GetBetaDist(q,n-xs+1,xs) );
}
- PushDouble(fSum);
}
}
else
@@ -1365,77 +1351,63 @@ void ScInterpreter::ScBinomDist()
RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScBinomDist" );
if ( MustHaveParamCount( GetByte(), 4 ) )
{
- double kum = GetDouble(); // 0 oder 1
- double p = GetDouble(); // p
- double n = ::rtl::math::approxFloor(GetDouble()); // n
- double x = ::rtl::math::approxFloor(GetDouble()); // x
- double fFactor, q, fSum;
+ bool bIsCum = GetBool(); // false=mass function; true=cumulative
+ double p = GetDouble();
+ double n = ::rtl::math::approxFloor(GetDouble());
+ double x = ::rtl::math::approxFloor(GetDouble());
+ double q = (0.5 - p) + 0.5; // get one bit more for p near 1.0
+ double fFactor, fSum;
if (n < 0.0 || x < 0.0 || x > n || p < 0.0 || p > 1.0)
- PushIllegalArgument();
- else if (kum == 0.0) // Dichte
{
- q = 1.0 - p;
- fFactor = pow(q, n);
- if (fFactor == 0.0)
- {
- fFactor = pow(p, n);
- if (fFactor == 0.0)
- PushNoValue();
- else
- {
- sal_uLong max = (sal_uLong) (n - x);
- for (sal_uLong i = 0; i < max && fFactor > 0.0; i++)
- fFactor *= (n-i)/(i+1)*q/p;
- PushDouble(fFactor);
- }
+ PushIllegalArgument();
+ return;
}
- else
+ if ( p == 0.0)
{
- sal_uLong max = (sal_uLong) x;
- for (sal_uLong i = 0; i < max && fFactor > 0.0; i++)
- fFactor *= (n-i)/(i+1)*p/q;
- PushDouble(fFactor);
+ PushDouble( (x==0.0 || bIsCum) ? 1.0 : 0.0 );
+ return;
}
+ if ( p == 1.0)
+ {
+ PushDouble( (x==n) ? 1.0 : 0.0);
+ return;
}
- else // Verteilung
+ if (!bIsCum)
+ PushDouble( GetBinomDistPMF(x,n,p));
+ else
{
- if (n == x)
+ if (x == n)
PushDouble(1.0);
else
{
- q = 1.0 - p;
fFactor = pow(q, n);
- if (fFactor == 0.0)
+ if (x == 0.0)
+ PushDouble(fFactor);
+ else
+ if (fFactor <= ::std::numeric_limits<double>::min())
{
fFactor = pow(p, n);
- if (fFactor == 0.0)
- PushNoValue();
+ if (fFactor <= ::std::numeric_limits<double>::min())
+ PushDouble(GetBetaDist(q,n-x,x+1.0));
else
{
+ if (fFactor > fMachEps)
+ {
fSum = 1.0 - fFactor;
- sal_uLong max = (sal_uLong) (n - x) - 1;
- for (sal_uLong i = 0; i < max && fFactor > 0.0; i++)
+ sal_uInt32 max = static_cast<sal_uInt32> (n - x) - 1;
+ for (sal_uInt32 i = 0; i < max && fFactor > 0.0; i++)
{
fFactor *= (n-i)/(i+1)*q/p;
fSum -= fFactor;
}
- if (fSum < 0.0)
- PushDouble(0.0);
- else
- PushDouble(fSum);
- }
+ PushDouble( (fSum < 0.0) ? 0.0 : fSum );
}
else
- {
- fSum = fFactor;
- sal_uLong max = (sal_uLong) x;
- for (sal_uLong i = 0; i < max && fFactor > 0.0; i++)
- {
- fFactor *= (n-i)/(i+1)*p/q;
- fSum += fFactor;
+ PushDouble(lcl_GetBinomDistRange(n,n-x,n,fFactor,q,p));
}
- PushDouble(fSum);
}
+ else
+ PushDouble( lcl_GetBinomDistRange(n,0.0,x,fFactor,p,q)) ;
}
}
}
diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx
index e3cd6239191e..439e0375a8b9 100755
--- a/sc/source/core/tool/interpr4.cxx
+++ b/sc/source/core/tool/interpr4.cxx
@@ -3181,6 +3181,14 @@ void ScInterpreter::ScColRowNameAuto()
void ScInterpreter::ScExternalRef()
{
+ const FormulaToken* pNextOp = aCode.PeekNextOperator();
+ if (pNextOp && pNextOp->GetOpCode() == ocOffset)
+ {
+ // Handled by OFFSET function.
+ PushTempToken( *pCur);
+ return;
+ }
+
ScExternalRefManager* pRefMgr = pDok->GetExternalRefManager();
const String* pFile = pRefMgr->getExternalFileName(pCur->GetIndex());
if (!pFile)
@@ -3324,6 +3332,21 @@ void ScInterpreter::GlobalExit() // static
}
+// A ::std::vector<FormulaTokenRef> is not possible, a push_back() attempts to
+// use a FormulaToken(const FormulaTokenRef&) ctor. Reinvent wheel..
+struct FormulaTokenRefPtr
+{
+ FormulaToken* mp;
+ FormulaTokenRefPtr() : mp(0) {}
+ FormulaTokenRefPtr( FormulaToken* p ) : mp(p) { if (mp) mp->IncRef(); }
+ FormulaTokenRefPtr( const FormulaTokenRefPtr & r ) : mp(r.mp) { if (mp) mp->IncRef(); }
+ ~FormulaTokenRefPtr() { if (mp) mp->DecRef(); }
+ FormulaTokenRefPtr& operator=( const FormulaTokenRefPtr & r )
+ { if (r.mp) r.mp->IncRef(); if (mp) mp->DecRef(); mp = r.mp; return *this; }
+};
+typedef ::std::vector< FormulaTokenRefPtr > FormulaTokenDtor;
+
+
StackVar ScInterpreter::Interpret()
{
RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::Interpret" );
@@ -3342,6 +3365,7 @@ StackVar ScInterpreter::Interpret()
pJumpMatrix = NULL;
glSubTotal = sal_False;
ScTokenMatrixMap::const_iterator aTokenMatrixMapIter;
+ ::boost::scoped_ptr< FormulaTokenDtor > pTokenDtor;
// Once upon a time we used to have FP exceptions on, and there was a
// Windows printer driver that kept switching off exceptions, so we had to
@@ -3724,13 +3748,27 @@ StackVar ScInterpreter::Interpret()
default : PushError( errUnknownOpCode); break;
}
- // If the function signalled that it pushed a subroutine on the
- // instruction code stack instead of a result, continue with
+ // If the function pushed a subroutine as result, continue with
// execution of the subroutine.
- if (sp > nStackBase && pStack[sp-1]->GetOpCode() == ocCall)
+ if (sp > nStackBase && pStack[sp-1]->GetOpCode() == ocCall && pStack[sp-1]->GetType() == svSubroutine)
{
- Pop();
- continue; // while( ( pCur = aCode.Next() ) != NULL ...
+ FormulaTokenRef xTok = PopToken();
+ const FormulaSubroutineToken* pSub = dynamic_cast<FormulaSubroutineToken*>(xTok.get());
+ if (pSub)
+ {
+ // Remember token for late destruction.
+ if (!pTokenDtor)
+ pTokenDtor.reset( new FormulaTokenDtor);
+ pTokenDtor->push_back( FormulaTokenDtor::value_type( xTok));
+ // Continue with execution of subroutine.
+ aCode.Push( pSub->GetTokenArray());
+ continue; // while( ( pCur = aCode.Next() ) != NULL ...
+ }
+ else
+ {
+ DBG_ERRORFILE( "ScInterpreter::Interpret: ocCall svSubroutine, but no FormulaSubroutineToken?!?");
+ PushError( errNoCode);
+ }
}
// Remember result matrix in case it could be reused.
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index a270969e100c..83ee5d365e63 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -561,6 +561,9 @@ sal_Bool ScToken::Is3DRef() const
if ( GetSingleRef().IsFlag3D() )
return sal_True;
break;
+ case svExternalSingleRef:
+ case svExternalDoubleRef:
+ return sal_True;
default:
{
// added to avoid warnings
@@ -922,6 +925,14 @@ ScExternalDoubleRefToken::ScExternalDoubleRefToken( const ScExternalDoubleRefTok
{
}
+ScExternalDoubleRefToken::ScExternalDoubleRefToken( const ScExternalSingleRefToken& r ) :
+ ScToken( svExternalDoubleRef, ocExternalRef),
+ mnFileId( r.GetIndex()),
+ maTabName( r.GetString())
+{
+ maDoubleRef.Ref1 = maDoubleRef.Ref2 = r.GetSingleRef();
+}
+
ScExternalDoubleRefToken::~ScExternalDoubleRefToken()
{
}
@@ -1825,6 +1836,20 @@ void ScTokenArray::ReadjustRelative3DReferences( const ScAddress& rOldPos,
}
}
break;
+ case svExternalDoubleRef:
+ {
+ ScSingleRefData& rRef2 = static_cast<ScToken*>(pCode[j])->GetSingleRef2();
+ rRef2.CalcAbsIfRel( rOldPos );
+ rRef2.CalcRelFromAbs( rNewPos );
+ }
+ //! fallthru
+ case svExternalSingleRef:
+ {
+ ScSingleRefData& rRef1 = static_cast<ScToken*>(pCode[j])->GetSingleRef();
+ rRef1.CalcAbsIfRel( rOldPos );
+ rRef1.CalcRelFromAbs( rNewPos );
+ }
+ break;
default:
{
// added to avoid warnings
diff --git a/sc/source/filter/xml/xmlexprt.cxx b/sc/source/filter/xml/xmlexprt.cxx
index ead8067ee23e..45c9b9dcc4c7 100644
--- a/sc/source/filter/xml/xmlexprt.cxx
+++ b/sc/source/filter/xml/xmlexprt.cxx
@@ -3255,6 +3255,9 @@ void ScXMLExport::WriteShapes(const ScMyCell& rMyCell)
AddAttribute(XML_NAMESPACE_TABLE, XML_END_Y, sBuffer.makeStringAndClear());
}
ExportShape(aItr->xShape, &aPoint);
+ // if there's an error in ExportShape, the attributes from above must be removed
+ CheckAttrList(); // asserts in non pro if we have attributes left
+ ClearAttrList(); // clears the attributes
}
++aItr;
}
diff --git a/sc/source/filter/xml/xmlimprt.cxx b/sc/source/filter/xml/xmlimprt.cxx
index d4133686d2c8..fb9241549817 100644
--- a/sc/source/filter/xml/xmlimprt.cxx
+++ b/sc/source/filter/xml/xmlimprt.cxx
@@ -73,6 +73,7 @@
#include "rangeutl.hxx"
#include "postit.hxx"
#include "formulaparserpool.hxx"
+#include "externalrefmgr.hxx"
#include <comphelper/extract.hxx>
#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
@@ -2857,9 +2858,19 @@ throw( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeE
}
GetProgressBarHelper()->End(); // make room for subsequent SfxProgressBars
if (pDoc)
+ {
pDoc->CompileXML();
- if (pDoc && GetModel().is())
+ // After CompileXML, links must be completely changed to the new URLs.
+ // Otherwise, hasExternalFile for API wouldn't work (#i116940#),
+ // and typing a new formula would create a second link with the same "real" file name.
+ if (pDoc->HasExternalRefManager())
+ pDoc->GetExternalRefManager()->updateAbsAfterLoad();
+ }
+
+ // If the stream contains cells outside of the current limits, the styles can't be re-created,
+ // so stream copying is disabled then.
+ if (pDoc && GetModel().is() && !pDoc->HasRangeOverflow())
{
// set "valid stream" flags after loading (before UpdateRowHeights, so changed formula results
// in UpdateRowHeights can already clear the flags again)
diff --git a/sc/source/filter/xml/xmlsubti.cxx b/sc/source/filter/xml/xmlsubti.cxx
index e6cc7b853764..3e182c919032 100644
--- a/sc/source/filter/xml/xmlsubti.cxx
+++ b/sc/source/filter/xml/xmlsubti.cxx
@@ -614,7 +614,8 @@ void ScMyTables::UpdateRowHeights()
if (aUpdateSheets.GetSelectCount())
{
pDoc->LockStreamValid( true ); // ignore draw page size (but not formula results)
- ScModelObj::getImplementation(rImport.GetModel())->UpdateAllRowHeights(&aUpdateSheets);
+ // #i114839# make sure the output factor is valid for UpdateAllRowHeights
+ ScModelObj::getImplementation(rImport.GetModel())->UpdateAllRowHeights(&aUpdateSheets, true);
pDoc->LockStreamValid( false );
}
}
diff --git a/sc/source/filter/xml/xmltabi.cxx b/sc/source/filter/xml/xmltabi.cxx
index 1644ad7e7ffe..dd234bb9a76a 100644
--- a/sc/source/filter/xml/xmltabi.cxx
+++ b/sc/source/filter/xml/xmltabi.cxx
@@ -55,6 +55,8 @@
#include <xmloff/xmltoken.hxx>
#include <xmloff/XMLEventsImportContext.hxx>
+#include <tools/urlobj.hxx>
+
#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
#include <com/sun/star/sheet/XSpreadsheets.hpp>
#include <com/sun/star/sheet/XSpreadsheet.hpp>
@@ -83,27 +85,29 @@ static bool lcl_isExternalRefCache(const rtl::OUString& rName, rtl::OUString& rU
// 'file:///path/to/file's.ods'#Sheet (Notice the quote in the file name.
// That's allowed.)
- static const sal_Unicode aPrefix[] = {
- '\'', 'f', 'i', 'l', 'e', ':', '/', '/'
- };
+ if ( rName.toChar() != '\'' ) // initial quote
+ return false;
+
+ // #i114504# Other schemes besides "file:" are also allowed.
+ // CompareProtocolScheme is quick, only looks at the start of the string.
+ INetProtocol eProt = INetURLObject::CompareProtocolScheme( rName.copy(1) );
+ if ( eProt == INET_PROT_NOT_VALID )
+ return false;
+
+ rtl::OUString aPrefix = INetURLObject::GetScheme( eProt );
+ sal_Int32 nPrefLen = aPrefix.getLength();
rtl::OUStringBuffer aUrlBuf, aTabNameBuf;
- aUrlBuf.appendAscii("file://");
+ aUrlBuf.append( aPrefix );
sal_Int32 n = rName.getLength();
const sal_Unicode* p = rName.getStr();
bool bInUrl = true;
sal_Unicode cPrev = 0;
- for (sal_Int32 i = 0; i < n; ++i)
+ for (sal_Int32 i = nPrefLen+1; i < n; ++i) // start the loop after quote and prefix
{
const sal_Unicode c = p[i];
- if (i <= 7)
- {
- // Checking the prefix 'file://'.
- if (c != aPrefix[i])
- return false;
- }
- else if (bInUrl)
+ if (bInUrl)
{
// parsing file URL
if (c == '#')
diff --git a/sc/source/ui/app/inputhdl.cxx b/sc/source/ui/app/inputhdl.cxx
index 33f6a279a40c..a6de38258d06 100644
--- a/sc/source/ui/app/inputhdl.cxx
+++ b/sc/source/ui/app/inputhdl.cxx
@@ -2097,7 +2097,7 @@ sal_Bool ScInputHandler::DataChanging( sal_Unicode cTyped, sal_Bool bFromCommand
return sal_False;
}
-void ScInputHandler::DataChanged( sal_Bool bFromTopNotify )
+void ScInputHandler::DataChanged( sal_Bool bFromTopNotify, sal_Bool bSetModified )
{
ImplCreateEditEngine();
@@ -2116,7 +2116,8 @@ void ScInputHandler::DataChanged( sal_Bool bFromTopNotify )
pTopView->ShowCursor();
}
- bModified = sal_True;
+ if (bSetModified)
+ bModified = sal_True;
bSelIsRef = sal_False;
if ( pRangeFindList && !bInRangeUpdate )
@@ -3207,7 +3208,9 @@ sal_Bool ScInputHandler::KeyInput( const KeyEvent& rKEvt, sal_Bool bStartEdit /*
}
}
- DataChanged(); // ruft auch UpdateParenthesis()
+ // #i114511# don't count cursor keys as modification
+ sal_Bool bSetModified = !bCursorKey;
+ DataChanged(sal_False, bSetModified); // also calls UpdateParenthesis()
InvalidateAttribs(); //! in DataChanged ?
}
}
diff --git a/sc/source/ui/dbgui/pvfundlg.cxx b/sc/source/ui/dbgui/pvfundlg.cxx
index 5ee9b320a04e..1bf258264dc9 100644
--- a/sc/source/ui/dbgui/pvfundlg.cxx
+++ b/sc/source/ui/dbgui/pvfundlg.cxx
@@ -748,8 +748,11 @@ ScDPShowDetailDlg::ScDPShowDetailDlg( Window* pParent, ScDPObject& rDPObj, sal_u
if (pLayoutName)
aName = *pLayoutName;
}
- maLbDims.InsertEntry( aName );
- maNameIndexMap.insert(DimNameIndexMap::value_type(aName, nDim));
+ if ( aName.Len() )
+ {
+ maLbDims.InsertEntry( aName );
+ maNameIndexMap.insert(DimNameIndexMap::value_type(aName, nDim));
+ }
}
}
}
diff --git a/sc/source/ui/dbgui/pvlaydlg.cxx b/sc/source/ui/dbgui/pvlaydlg.cxx
index a1a90731cf0f..e5709197748e 100644
--- a/sc/source/ui/dbgui/pvlaydlg.cxx
+++ b/sc/source/ui/dbgui/pvlaydlg.cxx
@@ -99,7 +99,7 @@ ScPivotLayoutDlg::ScPivotLayoutDlg( SfxBindings* pB, SfxChildWindow* pCW, Window
maFlAreas( this, ScResId( FL_OUTPUT ) ),
maFtInArea( this, ScResId( FT_INAREA) ),
- maEdInPos( this, ScResId( ED_INAREA) ),
+ maEdInPos( this, this, ScResId( ED_INAREA) ),
maRbInPos( this, ScResId( RB_INAREA ), &maEdInPos, this ),
maLbOutPos( this, ScResId( LB_OUTAREA ) ),
maFtOutArea( this, ScResId( FT_OUTAREA ) ),
diff --git a/sc/source/ui/docshell/docfunc.cxx b/sc/source/ui/docshell/docfunc.cxx
index 6414119677bf..e69458fd418b 100644
--- a/sc/source/ui/docshell/docfunc.cxx
+++ b/sc/source/ui/docshell/docfunc.cxx
@@ -2291,7 +2291,7 @@ sal_Bool ScDocFunc::MoveBlock( const ScRange& rSource, const ScAddress& rDestPos
}
ScDrawLayer::SetGlobalDrawPersist(aDragShellRef);
- ScClipParam aClipParam(ScRange(nStartCol, nStartRow, 0, nEndCol, nEndRow, 0), bCut);
+ ScClipParam aClipParam(ScRange(nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nStartTab), bCut);
pDoc->CopyToClip(aClipParam, pClipDoc, &aSourceMark, false, bScenariosAdded, true);
ScDrawLayer::SetGlobalDrawPersist(NULL);
diff --git a/sc/source/ui/docshell/externalrefmgr.cxx b/sc/source/ui/docshell/externalrefmgr.cxx
index e3293a7eed5b..a0581ec0d1c3 100644
--- a/sc/source/ui/docshell/externalrefmgr.cxx
+++ b/sc/source/ui/docshell/externalrefmgr.cxx
@@ -61,6 +61,7 @@
#include "sfx2/linkmgr.hxx"
#include "tools/urlobj.hxx"
#include "unotools/ucbhelper.hxx"
+#include "unotools/localfilehelper.hxx"
#include <memory>
#include <algorithm>
@@ -934,26 +935,6 @@ void ScExternalRefCache::getAllNumberFormats(vector<sal_uInt32>& rNumFmts) const
rNumFmts.swap(aNumFmts);
}
-bool ScExternalRefCache::hasCacheTable(sal_uInt16 nFileId, const String& rTabName) const
-{
- DocItem* pDoc = getDocItem(nFileId);
- if (!pDoc)
- return false;
-
- String aUpperName = ScGlobal::pCharClass->upper(rTabName);
- vector<TableName>::const_iterator itrBeg = pDoc->maTableNames.begin(), itrEnd = pDoc->maTableNames.end();
- vector<TableName>::const_iterator itr = ::std::find_if(
- itrBeg, itrEnd, TabNameSearchPredicate(aUpperName));
-
- return itr != itrEnd;
-}
-
-size_t ScExternalRefCache::getCacheTableCount(sal_uInt16 nFileId) const
-{
- DocItem* pDoc = getDocItem(nFileId);
- return pDoc ? pDoc->maTables.size() : 0;
-}
-
bool ScExternalRefCache::setCacheDocReferenced( sal_uInt16 nFileId )
{
DocItem* pDocItem = getDocItem(nFileId);
@@ -1576,16 +1557,6 @@ void ScExternalRefManager::getAllCachedNumberFormats(vector<sal_uInt32>& rNumFmt
maRefCache.getAllNumberFormats(rNumFmts);
}
-bool ScExternalRefManager::hasCacheTable(sal_uInt16 nFileId, const String& rTabName) const
-{
- return maRefCache.hasCacheTable(nFileId, rTabName);
-}
-
-size_t ScExternalRefManager::getCacheTableCount(sal_uInt16 nFileId) const
-{
- return maRefCache.getCacheTableCount(nFileId);
-}
-
sal_uInt16 ScExternalRefManager::getExternalFileCount() const
{
return static_cast< sal_uInt16 >( maSrcFiles.size() );
@@ -2026,7 +1997,10 @@ SfxObjectShellRef ScExternalRefManager::loadSrcDocument(sal_uInt16 nFileId, Stri
return NULL;
String aOptions( pFileData->maFilterOptions );
- ScDocumentLoader::GetFilterName(aFile, rFilter, aOptions, true, false);
+ if ( pFileData->maFilterName.Len() )
+ rFilter = pFileData->maFilterName; // don't overwrite stored filter with guessed filter
+ else
+ ScDocumentLoader::GetFilterName(aFile, rFilter, aOptions, true, false);
const SfxFilter* pFilter = ScDocShell::Factory().GetFilterContainer()->GetFilter4FilterName(rFilter);
if (!pFileData->maRelativeName.Len())
@@ -2093,10 +2067,18 @@ bool ScExternalRefManager::isFileLoadable(const String& rFile) const
if (isOwnDocument(rFile))
return false;
- if (utl::UCBContentHelper::IsFolder(rFile))
- return false;
+ String aPhysical;
+ if (utl::LocalFileHelper::ConvertURLToPhysicalName(rFile, aPhysical) && aPhysical.Len())
+ {
+ // #i114504# try IsFolder/Exists only for file URLs
+
+ if (utl::UCBContentHelper::IsFolder(rFile))
+ return false;
- return utl::UCBContentHelper::Exists(rFile);
+ return utl::UCBContentHelper::Exists(rFile);
+ }
+ else
+ return true; // for http and others, Exists doesn't work, but the URL can still be opened
}
void ScExternalRefManager::maybeLinkExternalFile(sal_uInt16 nFileId)
@@ -2111,7 +2093,16 @@ void ScExternalRefManager::maybeLinkExternalFile(sal_uInt16 nFileId)
return;
String aFilter, aOptions;
- ScDocumentLoader::GetFilterName(*pFileName, aFilter, aOptions, true, false);
+ const SrcFileData* pFileData = getExternalFileData(nFileId);
+ if (pFileData)
+ {
+ aFilter = pFileData->maFilterName;
+ aOptions = pFileData->maFilterOptions;
+ }
+ // If a filter was already set (for example, loading the cached table),
+ // don't call GetFilterName which has to access the source file.
+ if (!aFilter.Len())
+ ScDocumentLoader::GetFilterName(*pFileName, aFilter, aOptions, true, false);
sfx2::LinkManager* pLinkMgr = mpDoc->GetLinkManager();
ScExternalRefLink* pLink = new ScExternalRefLink(mpDoc, nFileId, aFilter);
DBG_ASSERT(pFileName, "ScExternalRefManager::insertExternalFileLink: file name pointer is NULL");
@@ -2344,6 +2335,22 @@ void ScExternalRefManager::resetSrcFileData(const String& rBaseFileUrl)
}
}
+void ScExternalRefManager::updateAbsAfterLoad()
+{
+ String aOwn( getOwnDocumentName() );
+ for (vector<SrcFileData>::iterator itr = maSrcFiles.begin(), itrEnd = maSrcFiles.end();
+ itr != itrEnd; ++itr)
+ {
+ // update maFileName to the real file name,
+ // to be called when the original name is no longer needed (after CompileXML)
+
+ itr->maybeCreateRealFileName( aOwn );
+ String aReal = itr->maRealFileName;
+ if (aReal.Len())
+ itr->maFileName = aReal;
+ }
+}
+
void ScExternalRefManager::removeRefCell(ScFormulaCell* pCell)
{
for_each(maRefCells.begin(), maRefCells.end(), RemoveFormulaCell(pCell));
diff --git a/sc/source/ui/inc/inputhdl.hxx b/sc/source/ui/inc/inputhdl.hxx
index 8291877bbc57..9f745b4cd96c 100644
--- a/sc/source/ui/inc/inputhdl.hxx
+++ b/sc/source/ui/inc/inputhdl.hxx
@@ -211,7 +211,7 @@ public:
EditView* GetTopView() { return pTopView; }
sal_Bool DataChanging( sal_Unicode cTyped = 0, sal_Bool bFromCommand = sal_False );
- void DataChanged( sal_Bool bFromTopNotify = sal_False );
+ void DataChanged( sal_Bool bFromTopNotify = sal_False, sal_Bool bSetModified = sal_True );
sal_Bool TakesReturn() const { return ( nTipVisible != 0 ); }
diff --git a/sc/source/ui/styleui/scstyles.src b/sc/source/ui/styleui/scstyles.src
index 1968b6dca877..07e4dbd85151 100644
--- a/sc/source/ui/styleui/scstyles.src
+++ b/sc/source/ui/styleui/scstyles.src
@@ -31,6 +31,19 @@
StyleFamily = family; \
FilterList = { filter }
+String STR_STYLE_FILTER_USED
+{
+ Text [ en-US ] = "Applied Styles" ;
+};
+String STR_STYLE_FILTER_USERDEF
+{
+ Text [ en-US ] = "Custom Styles" ;
+};
+String STR_STYLE_FILTER_ALL
+{
+ Text [ en-US ] = "All Styles" ;
+};
+
//------------------------------------------------------------------------
SfxStyleFamilies DLG_STYLE_DESIGNER
{
diff --git a/sc/source/ui/unoobj/addruno.cxx b/sc/source/ui/unoobj/addruno.cxx
index e54c47b6bd64..0dde4fb9e880 100644
--- a/sc/source/ui/unoobj/addruno.cxx
+++ b/sc/source/ui/unoobj/addruno.cxx
@@ -195,7 +195,7 @@ void SAL_CALL ScAddressConversionObj::setPropertyValue( const rtl::OUString& aPr
else if ( aNameStr.EqualsAscii( SC_UNONAME_PERSREPR ) || aNameStr.EqualsAscii( SC_UNONAME_XLA1REPR ) )
{
::formula::FormulaGrammar::AddressConvention eConv = aNameStr.EqualsAscii( SC_UNONAME_XLA1REPR ) ?
- ::formula::FormulaGrammar::CONV_OOO : ::formula::FormulaGrammar::CONV_XL_A1;
+ ::formula::FormulaGrammar::CONV_XL_A1 : ::formula::FormulaGrammar::CONV_OOO;
// parse the file format string
rtl::OUString sRepresentation;
@@ -273,7 +273,7 @@ uno::Any SAL_CALL ScAddressConversionObj::getPropertyValue( const rtl::OUString&
else if ( aNameStr.EqualsAscii( SC_UNONAME_PERSREPR ) || aNameStr.EqualsAscii( SC_UNONAME_XLA1REPR ) )
{
::formula::FormulaGrammar::AddressConvention eConv = aNameStr.EqualsAscii( SC_UNONAME_XLA1REPR ) ?
- ::formula::FormulaGrammar::CONV_OOO : ::formula::FormulaGrammar::CONV_XL_A1;
+ ::formula::FormulaGrammar::CONV_XL_A1 : ::formula::FormulaGrammar::CONV_OOO;
// generate file format string - always include sheet
String aFormatStr;
diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx
index b47c0aac3163..d3ab32c66e81 100644
--- a/sc/source/ui/unoobj/docuno.cxx
+++ b/sc/source/ui/unoobj/docuno.cxx
@@ -412,10 +412,14 @@ SfxObjectShell* ScModelObj::GetEmbeddedObject() const
return pDocShell;
}
-void ScModelObj::UpdateAllRowHeights(const ScMarkData* pTabMark)
+void ScModelObj::UpdateAllRowHeights(const ScMarkData* pTabMark, bool bCalcOutputFactor)
{
if (pDocShell)
+ {
+ if (bCalcOutputFactor)
+ pDocShell->CalcOutputFactor();
pDocShell->UpdateAllRowHeights(pTabMark);
+ }
}
void ScModelObj::BeforeXMLLoading()
diff --git a/sc/source/ui/unoobj/linkuno.cxx b/sc/source/ui/unoobj/linkuno.cxx
index ee6c3ff1988a..8b9e1039f085 100644
--- a/sc/source/ui/unoobj/linkuno.cxx
+++ b/sc/source/ui/unoobj/linkuno.cxx
@@ -1641,10 +1641,17 @@ Sequence< OUString > SAL_CALL ScExternalDocLinkObj::getElementNames()
ScUnoGuard aGuard;
vector<String> aTabNames;
mpRefMgr->getAllCachedTableNames(mnFileId, aTabNames);
- size_t n = aTabNames.size();
+
+ // #i116940# be consistent with getByName: include only table names which have a cache already
+ vector<String> aValidNames;
+ for (vector<String>::const_iterator aIter = aTabNames.begin(); aIter != aTabNames.end(); ++aIter)
+ if (mpRefMgr->getCacheTable(mnFileId, *aIter, false))
+ aValidNames.push_back(*aIter);
+
+ size_t n = aValidNames.size();
Sequence<OUString> aSeq(n);
for (size_t i = 0; i < n; ++i)
- aSeq[i] = aTabNames[i];
+ aSeq[i] = aValidNames[i];
return aSeq;
}
@@ -1652,25 +1659,35 @@ sal_Bool SAL_CALL ScExternalDocLinkObj::hasByName(const OUString &aName)
throw (RuntimeException)
{
ScUnoGuard aGuard;
- return static_cast<sal_Bool>(mpRefMgr->hasCacheTable(mnFileId, aName));
+
+ // #i116940# be consistent with getByName: allow only table names which have a cache already
+ ScExternalRefCache::TableTypeRef pTable = mpRefMgr->getCacheTable(mnFileId, aName, false);
+ return (pTable.get() != NULL);
}
sal_Int32 SAL_CALL ScExternalDocLinkObj::getCount()
throw (RuntimeException)
{
ScUnoGuard aGuard;
- return static_cast<sal_Int32>(mpRefMgr->getCacheTableCount(mnFileId));
+
+ // #i116940# be consistent with getByName: count only table names which have a cache already
+ return getElementNames().getLength();
}
-Any SAL_CALL ScExternalDocLinkObj::getByIndex(sal_Int32 nIndex)
+Any SAL_CALL ScExternalDocLinkObj::getByIndex(sal_Int32 nApiIndex)
throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, RuntimeException)
{
ScUnoGuard aGuard;
- size_t nTabCount = mpRefMgr->getCacheTableCount(mnFileId);
- if (nIndex < 0 || nIndex >= static_cast<sal_Int32>(nTabCount))
+
+ // #i116940# Can't use nApiIndex as index for the ref manager, because the API counts only
+ // the entries which have a cache already. Quick solution: Use getElementNames.
+
+ Sequence< OUString > aNames( getElementNames() );
+ if (nApiIndex < 0 || nApiIndex >= aNames.getLength())
throw lang::IndexOutOfBoundsException();
- ScExternalRefCache::TableTypeRef pTable = mpRefMgr->getCacheTable(mnFileId, static_cast<size_t>(nIndex));
+ size_t nIndex = 0;
+ ScExternalRefCache::TableTypeRef pTable = mpRefMgr->getCacheTable(mnFileId, aNames[nApiIndex], false, &nIndex);
if (!pTable)
throw lang::IndexOutOfBoundsException();
@@ -1702,7 +1719,9 @@ sal_Bool SAL_CALL ScExternalDocLinkObj::hasElements()
throw (RuntimeException)
{
ScUnoGuard aGuard;
- return static_cast<sal_Bool>(mpRefMgr->getCacheTableCount(mnFileId) > 0);
+
+ // #i116940# be consistent with getByName: count only table names which have a cache already
+ return ( getElementNames().getLength() > 0 );
}
sal_Int32 SAL_CALL ScExternalDocLinkObj::getTokenIndex()
diff --git a/sc/source/ui/view/editsh.cxx b/sc/source/ui/view/editsh.cxx
index e07e15267198..f75ebcbe770f 100644
--- a/sc/source/ui/view/editsh.cxx
+++ b/sc/source/ui/view/editsh.cxx
@@ -199,6 +199,7 @@ void ScEditShell::Execute( SfxRequest& rReq )
pHdl->DataChanging();
sal_Bool bSetSelIsRef = sal_False;
+ sal_Bool bSetModified = sal_True;
switch ( nSlot )
{
@@ -234,6 +235,7 @@ void ScEditShell::Execute( SfxRequest& rReq )
case SID_COPY:
pTableView->Copy();
+ bSetModified = sal_False;
break;
case SID_CUT:
@@ -334,6 +336,7 @@ void ScEditShell::Execute( SfxRequest& rReq )
if (pTopView)
pTopView->SetSelection(ESelection(0,0,nPar-1,nLen));
}
+ bSetModified = sal_False;
}
break;
@@ -615,7 +618,7 @@ void ScEditShell::Execute( SfxRequest& rReq )
break;
}
- pHdl->DataChanged();
+ pHdl->DataChanged(sal_False, bSetModified);
if (bSetSelIsRef)
pHdl->SetSelIsRef(sal_True);
}
diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx
index 335f5ad14490..d58d2266618d 100644
--- a/sc/source/ui/view/gridwin.cxx
+++ b/sc/source/ui/view/gridwin.cxx
@@ -2,7 +2,7 @@
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
- * Copyright 2000, 2010 Oracle and/or its affiliates.
+ * Copyright 2000, 2011 Oracle and/or its affiliates.
*
* OpenOffice.org - a multi-platform office productivity suite
*
@@ -1682,6 +1682,7 @@ void ScGridWindow::HandleMouseButtonDown( const MouseEvent& rMEvt )
pDoc->GetAttr( nPosX, nPosY, nTab, ATTR_MERGE_FLAG );
if (pAttr->HasAutoFilter())
{
+ SC_MOD()->InputEnterHandler(); //Add for i85305
if (DoAutoFilterButton(nPosX, nPosY, rMEvt))
return;
}
diff --git a/sc/source/ui/view/gridwin2.cxx b/sc/source/ui/view/gridwin2.cxx
index 67cc1d318fdb..89fd1027877d 100644
--- a/sc/source/ui/view/gridwin2.cxx
+++ b/sc/source/ui/view/gridwin2.cxx
@@ -456,6 +456,18 @@ private:
}
+bool lcl_GetLabelIndex( size_t& rLabelIndex, long nDimension, const ScDPLabelDataVector& rLabelArray )
+{
+ size_t n = rLabelArray.size();
+ for (size_t i = 0; i < n; ++i)
+ if (static_cast<long>(rLabelArray[i].mnCol) == nDimension)
+ {
+ rLabelIndex = i;
+ return true;
+ }
+ return false;
+}
+
void ScGridWindow::DPLaunchFieldPopupMenu(
const Point& rScrPos, const Size& rScrSize, const ScAddress& rPos, ScDPObject* pDPObj)
{
@@ -467,11 +479,12 @@ void ScGridWindow::DPLaunchFieldPopupMenu(
sal_uInt16 nOrient;
pDPData->mnDim = pDPObj->GetHeaderDim(rPos, nOrient);
- if (pDPData->maDPParam.maLabelArray.size() <= static_cast<size_t>(pDPData->mnDim))
- // out-of-bound dimension ID. This should never happen!
+ // #i116457# FillLabelData skips empty column names, so mnDim can't be used directly as index into maLabelArray.
+ size_t nLabelIndex = 0;
+ if (!lcl_GetLabelIndex( nLabelIndex, pDPData->mnDim, pDPData->maDPParam.maLabelArray ))
return;
- const ScDPLabelData& rLabelData = pDPData->maDPParam.maLabelArray[pDPData->mnDim];
+ const ScDPLabelData& rLabelData = pDPData->maDPParam.maLabelArray[nLabelIndex];
mpDPFieldPopup.reset(new ScDPFieldPopupWindow(this, pViewData->GetDocument()));
mpDPFieldPopup->setName(OUString::createFromAscii("Pivot table field member popup"));
@@ -567,8 +580,11 @@ void ScGridWindow::UpdateDPFromFieldPopupMenu()
if (!pDim)
return;
+ size_t nLabelIndex = 0;
+ lcl_GetLabelIndex( nLabelIndex, pDPData->mnDim, pDPData->maDPParam.maLabelArray );
+
// Build a map of layout names to original names.
- const ScDPLabelData& rLabelData = pDPData->maDPParam.maLabelArray[pDPData->mnDim];
+ const ScDPLabelData& rLabelData = pDPData->maDPParam.maLabelArray[nLabelIndex];
MemNameMapType aMemNameMap;
for (vector<ScDPLabelData::Member>::const_iterator itr = rLabelData.maMembers.begin(), itrEnd = rLabelData.maMembers.end();
itr != itrEnd; ++itr)
diff --git a/sc/source/ui/view/output2.cxx b/sc/source/ui/view/output2.cxx
index 2df47d16e195..0b9a1c4084e4 100644
--- a/sc/source/ui/view/output2.cxx
+++ b/sc/source/ui/view/output2.cxx
@@ -75,8 +75,6 @@
#include "scmod.hxx"
#include "fillinfo.hxx"
-#include <boost/ptr_container/ptr_vector.hpp>
-
#include <math.h>
//! Autofilter-Breite mit column.cxx zusammenfassen
@@ -154,6 +152,8 @@ public:
const Size& GetTextSize() const { return aTextSize; }
long GetOriginalWidth() const { return nOriginalWidth; }
+ sal_uLong GetResultValueFormat( const ScBaseCell* pCell ) const;
+
sal_uLong GetValueFormat() const { return nValueFormat; }
sal_Bool GetLineBreak() const { return bLineBreak; }
sal_Bool IsRepeat() const { return bRepeat; }
@@ -542,7 +542,7 @@ void ScDrawStringsVars::SetTextToWidthOrHash( ScBaseCell* pCell, long nWidth )
return;
}
- sal_uLong nFormat = GetValueFormat();
+ sal_uLong nFormat = GetResultValueFormat(pCell);
if ((nFormat % SV_COUNTRY_LANGUAGE_OFFSET) != 0)
{
// Not 'General' number format. Set hash text and bail out.
@@ -719,6 +719,17 @@ sal_Bool ScDrawStringsVars::HasEditCharacters() const
return aString.SearchChar( pChars ) != STRING_NOTFOUND;
}
+sal_uLong ScDrawStringsVars::GetResultValueFormat( const ScBaseCell* pCell ) const
+{
+ // Get the effective number format, including formula result types.
+ // This assumes that a formula cell has already been calculated.
+
+ if ( (nValueFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0 && pCell && pCell->GetCellType() == CELLTYPE_FORMULA )
+ return static_cast<const ScFormulaCell*>(pCell)->GetStandardFormat(*pOutput->pDoc->GetFormatTable(), nValueFormat);
+ else
+ return nValueFormat;
+}
+
//==================================================================
double ScOutputData::GetStretch()
@@ -1361,10 +1372,6 @@ void ScOutputData::DrawStrings( sal_Bool bPixelToLogic )
const SfxItemSet* pOldCondSet = NULL;
sal_uInt8 nOldScript = 0;
- // alternative pattern instances in case we need to modify the pattern
- // before processing the cell value.
- ::boost::ptr_vector<ScPatternAttr> aAltPatterns;
-
long nPosY = nScrY;
for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
{
@@ -1501,18 +1508,6 @@ void ScOutputData::DrawStrings( sal_Bool bPixelToLogic )
pCondSet = pDoc->GetCondResult( nCellX, nCellY, nTab );
}
- if (pCell->HasValueData() &&
- static_cast<const SfxBoolItem&>(
- pPattern->GetItem(ATTR_LINEBREAK, pCondSet)).GetValue())
- {
- // Disable line break when the cell content is numeric.
- aAltPatterns.push_back(new ScPatternAttr(*pPattern));
- ScPatternAttr* pAltPattern = &aAltPatterns.back();
- SfxBoolItem aLineBreak(ATTR_LINEBREAK, false);
- pAltPattern->GetItemSet().Put(aLineBreak);
- pPattern = pAltPattern;
- }
-
sal_uInt8 nScript = GetScriptType( pDoc, pCell, pPattern, pCondSet );
if (nScript == 0) nScript = ScGlobal::GetDefaultScriptType();
if ( pPattern != pOldPattern || pCondSet != pOldCondSet ||
@@ -1562,6 +1557,11 @@ void ScOutputData::DrawStrings( sal_Bool bPixelToLogic )
eOutHorJust = SVX_HOR_JUSTIFY_LEFT; // repeat is not yet implemented
sal_Bool bBreak = ( aVars.GetLineBreak() || aVars.GetHorJust() == SVX_HOR_JUSTIFY_BLOCK );
+
+ // #i111387# #o11817313# disable automatic line breaks only for "General" number format
+ if ( bBreak && bCellIsValue && ( aVars.GetResultValueFormat(pCell) % SV_COUNTRY_LANGUAGE_OFFSET ) == 0 )
+ bBreak = sal_False;
+
sal_Bool bRepeat = aVars.IsRepeat() && !bBreak;
sal_Bool bShrink = aVars.IsShrink() && !bBreak && !bRepeat;
diff --git a/sc/source/ui/view/tabcont.cxx b/sc/source/ui/view/tabcont.cxx
index 6e41548dc31f..48de6a0ee731 100644
--- a/sc/source/ui/view/tabcont.cxx
+++ b/sc/source/ui/view/tabcont.cxx
@@ -458,12 +458,13 @@ void ScTabControl::DoDrag( const Region& /* rRegion */ )
ScDocument* pDoc = pDocSh->GetDocument();
SCTAB nTab = pViewData->GetTabNo();
+ ScRange aTabRange( 0, 0, nTab, MAXCOL, MAXROW, nTab );
ScMarkData aTabMark = pViewData->GetMarkData();
aTabMark.ResetMark(); // doesn't change marked table information
- aTabMark.SetMarkArea( ScRange(0,0,nTab,MAXCOL,MAXROW,nTab) );
+ aTabMark.SetMarkArea( aTabRange );
ScDocument* pClipDoc = new ScDocument( SCDOCMODE_CLIP );
- ScClipParam aClipParam(ScRange(0, 0, 0, MAXCOL, MAXROW, 0), false);
+ ScClipParam aClipParam(aTabRange, false);
pDoc->CopyToClip(aClipParam, pClipDoc, &aTabMark, false);
TransferableObjectDescriptor aObjDesc;
diff --git a/sc/source/ui/view/viewfun3.cxx b/sc/source/ui/view/viewfun3.cxx
index 0f4893cf3512..f25aa500cc72 100644
--- a/sc/source/ui/view/viewfun3.cxx
+++ b/sc/source/ui/view/viewfun3.cxx
@@ -1104,7 +1104,20 @@ sal_Bool ScViewFunc::PasteFromClip( sal_uInt16 nFlags, ScDocument* pClipDoc,
if (nBlockAddX > nDestSizeX)
nMarkAddX = nBlockAddX - nDestSizeX; // fuer Merge-Test
else
+ {
nEndCol = nStartCol + nDestSizeX;
+ if (nEndCol > aMarkRange.aEnd.Col())
+ {
+ // #i113553# larger range has to be included in aFilteredMark (for undo), but extending columns can't changed the filtered status
+ aMarkRange = ScRange( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab );
+ aFilteredMark.SetMarkArea( aMarkRange );
+ if (bMarkIsFiltered)
+ {
+ ScViewUtil::UnmarkFiltered( aFilteredMark, pDoc );
+ aFilteredMark.FillRangeListWithMarks( &aRangeList, sal_True );
+ }
+ }
+ }
if (nBlockAddY > nDestSizeY)
nMarkAddY = nBlockAddY - nDestSizeY; // fuer Merge-Test
diff --git a/sc/source/ui/view/viewfun5.cxx b/sc/source/ui/view/viewfun5.cxx
index fff42faecb51..1d2b636c4259 100644
--- a/sc/source/ui/view/viewfun5.cxx
+++ b/sc/source/ui/view/viewfun5.cxx
@@ -165,7 +165,7 @@ sal_Bool ScViewFunc::PasteDataFormat( sal_uLong nFormatId,
nFirstCol = nLastCol = 0;
nFirstRow = nLastRow = 0;
}
- ScClipParam aClipParam(ScRange(nFirstCol, nFirstRow, 0, nLastCol, nLastRow, 0), false);
+ ScClipParam aClipParam(ScRange(nFirstCol, nFirstRow, nSrcTab, nLastCol, nLastRow, nSrcTab), false);
pSrcDoc->CopyToClip(aClipParam, pClipDoc, &aSrcMark);
ScGlobal::SetClipDocName( xDocShRef->GetTitle( SFX_TITLE_FULLNAME ) );