/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sc.hxx" #include #include #include "dbcolect.hxx" #include "global.hxx" #include "refupdat.hxx" #include "rechead.hxx" #include "document.hxx" #include "queryparam.hxx" #include "globstr.hrc" #define SC_DBNAME_UNNAMED "__Anonymous_Sheet_DB__" //--------------------------------------------------------------------------------------- ScDBData::ScDBData( const String& rName, SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, sal_Bool bByR, sal_Bool bHasH) : aName (rName), nTable (nTab), nStartCol (nCol1), nStartRow (nRow1), nEndCol (nCol2), nEndRow (nRow2), bByRow (bByR), bHasHeader (bHasH), bDoSize (sal_False), bKeepFmt (sal_False), bStripData (sal_False), bIsAdvanced (sal_False), bDBSelection(sal_False), nIndex (0), bAutoFilter (sal_False), bModified (sal_False) { sal_uInt16 i; ScSortParam aSortParam; ScQueryParam aQueryParam; ScSubTotalParam aSubTotalParam; ScImportParam aImportParam; for (i=0; i 0 ? new ScSubTotalFunc [nCount] : NULL; pSubTotals[i] = nCount > 0 ? new SCCOL [nCount] : NULL; for (j=0; j 0 ? new SCCOL [nCount] : NULL; pFunctions[i] = nCount > 0 ? new ScSubTotalFunc [nCount] : NULL; for (j=0; j nMaxRow || //UNUSED2008-05 nEndRow > nMaxRow || //UNUSED2008-05 nQueryDestRow > nMaxRow ); //UNUSED2008-05 } String ScDBData::GetSourceString() const { String aVal; if (bDBImport) { aVal = aDBName; aVal += '/'; aVal += aDBStatement; } return aVal; } String ScDBData::GetOperations() const { String aVal; if (bDoQuery[0]) aVal = ScGlobal::GetRscString(STR_OPERATION_FILTER); if (bDoSort[0]) { if (aVal.Len()) aVal.AppendAscii( RTL_CONSTASCII_STRINGPARAM(", ") ); aVal += ScGlobal::GetRscString(STR_OPERATION_SORT); } if (bDoSubTotal[0] && !bSubRemoveOnly) { if (aVal.Len()) aVal.AppendAscii( RTL_CONSTASCII_STRINGPARAM(", ") ); aVal += ScGlobal::GetRscString(STR_OPERATION_SUBTOTAL); } if (!aVal.Len()) aVal = ScGlobal::GetRscString(STR_OPERATION_NONE); return aVal; } void ScDBData::GetArea(SCTAB& rTab, SCCOL& rCol1, SCROW& rRow1, SCCOL& rCol2, SCROW& rRow2) const { rTab = nTable; rCol1 = nStartCol; rRow1 = nStartRow; rCol2 = nEndCol; rRow2 = nEndRow; } void ScDBData::GetArea(ScRange& rRange) const { rRange = ScRange( nStartCol,nStartRow,nTable, nEndCol,nEndRow,nTable ); } void ScDBData::SetArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) { nTable = nTab; nStartCol = nCol1; nStartRow = nRow1; nEndCol = nCol2; nEndRow = nRow2; } void ScDBData::MoveTo(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) { sal_uInt16 i; long nDifX = ((long) nCol1) - ((long) nStartCol); long nDifY = ((long) nRow1) - ((long) nStartRow); long nSortDif = bByRow ? nDifX : nDifY; long nSortEnd = bByRow ? static_cast(nCol2) : static_cast(nRow2); for (i=0; i nSortEnd) { nSortField[i] = 0; bDoSort[i] = sal_False; } } for (i=0; i nCol2) { nQueryField[i] = 0; bDoQuery[i] = sal_False; } } for (i=0; i( nSubField[i] + nDifX ); if (nSubField[i] > nCol2) { nSubField[i] = 0; bDoSubTotal[i] = sal_False; } } SetArea( nTab, nCol1, nRow1, nCol2, nRow2 ); } void ScDBData::GetSortParam( ScSortParam& rSortParam ) const { rSortParam.nCol1 = nStartCol; rSortParam.nRow1 = nStartRow; rSortParam.nCol2 = nEndCol; rSortParam.nRow2 = nEndRow; rSortParam.bByRow = bByRow; rSortParam.bHasHeader = bHasHeader; rSortParam.bCaseSens = bSortCaseSens; rSortParam.bInplace = bSortInplace; rSortParam.nDestTab = nSortDestTab; rSortParam.nDestCol = nSortDestCol; rSortParam.nDestRow = nSortDestRow; rSortParam.bIncludePattern = bIncludePattern; rSortParam.bUserDef = bSortUserDef; rSortParam.nUserIndex = nSortUserIndex; for (sal_uInt16 i=0; i 0 ? new SCCOL[nCount] : NULL; rSubTotalParam.pFunctions[i] = nCount > 0 ? new ScSubTotalFunc[nCount] : NULL; for (j=0; j 0 ? new SCCOL [nCount] : NULL; pFunctions[i] = nCount > 0 ? new ScSubTotalFunc [nCount] : NULL; for (j=0; j= nStartCol && nCol <= nEndCol && nRow >= nStartRow && nRow <= nEndRow ); } return sal_False; } sal_Bool ScDBData::IsDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const { return (sal_Bool)((nTab == nTable) && (nCol1 == nStartCol) && (nRow1 == nStartRow) && (nCol2 == nEndCol) && (nRow2 == nEndRow)); } ScDataObject* ScDBData::Clone() const { return new ScDBData(*this); } sal_Bool ScDBData::IsBuildin() { String aNoName = String::CreateFromAscii(SC_DBNAME_UNNAMED); String aBeginName = aName.Copy(0,22); return (sal_Bool)(!ScGlobal::GetpTransliteration()->compareString( aNoName, aBeginName )); } //--------------------------------------------------------------------------------------- // Compare zum Sortieren short ScDBCollection::Compare(ScDataObject* pKey1, ScDataObject* pKey2) const { const String& rStr1 = ((ScDBData*)pKey1)->GetName(); const String& rStr2 = ((ScDBData*)pKey2)->GetName(); return (short) ScGlobal::GetpTransliteration()->compareString( rStr1, rStr2 ); } // IsEqual - alles gleich sal_Bool ScDBCollection::IsEqual(ScDataObject* pKey1, ScDataObject* pKey2) const { return *(ScDBData*)pKey1 == *(ScDBData*)pKey2; } ScDBData* ScDBCollection::GetDBAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, sal_Bool bStartOnly) const { ScDBData* pNoNameData = NULL; if (pItems) { for (sal_uInt16 i = 0; i < nCount; i++) if (((ScDBData*)pItems[i])->IsDBAtCursor(nCol, nRow, nTab, bStartOnly)) { ScDBData* pDB = (ScDBData*)pItems[i]; if ( pDB->IsBuildin() ) pNoNameData = pDB; else return pDB; } } return pNoNameData; // "unbenannt" nur zurueck, wenn sonst nichts gefunden } ScDBData* ScDBCollection::GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const { ScDBData* pNoNameData = NULL; if (pItems) { for (sal_uInt16 i = 0; i < nCount; i++) if (((ScDBData*)pItems[i])->IsDBAtArea(nTab, nCol1, nRow1, nCol2, nRow2)) { ScDBData* pDB = (ScDBData*)pItems[i]; if ( pDB->IsBuildin() ) pNoNameData = pDB; else return pDB; } } 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 ); return Search( &aDataObj, rIndex ); } void ScDBCollection::DeleteOnTab( SCTAB nTab ) { sal_uInt16 nPos = 0; while ( nPos < nCount ) { // look for output positions on the deleted sheet SCCOL nEntryCol1, nEntryCol2; SCROW nEntryRow1, nEntryRow2; SCTAB nEntryTab; static_cast(At(nPos))->GetArea( nEntryTab, nEntryCol1, nEntryRow1, nEntryCol2, nEntryRow2 ); if ( nEntryTab == nTab ) AtFree(nPos); else ++nPos; } } void ScDBCollection::UpdateReference(UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2, SCsCOL nDx, SCsROW nDy, SCsTAB nDz ) { for (sal_uInt16 i=0; iGetArea( theTab1, theCol1, theRow1, theCol2, theRow2 ); theTab2 = theTab1; sal_Bool bDoUpdate = ScRefUpdate::Update( pDoc, eUpdateRefMode, nCol1,nRow1,nTab1, nCol2,nRow2,nTab2, nDx,nDy,nDz, theCol1,theRow1,theTab1, theCol2,theRow2,theTab2 ) != UR_NOTHING; if (bDoUpdate) ((ScDBData*)pItems[i])->MoveTo( theTab1, theCol1, theRow1, theCol2, theRow2 ); ScRange aAdvSource; if ( ((ScDBData*)pItems[i])->GetAdvancedQuerySource(aAdvSource) ) { aAdvSource.GetVars( theCol1,theRow1,theTab1, theCol2,theRow2,theTab2 ); if ( ScRefUpdate::Update( pDoc, eUpdateRefMode, nCol1,nRow1,nTab1, nCol2,nRow2,nTab2, nDx,nDy,nDz, theCol1,theRow1,theTab1, theCol2,theRow2,theTab2 ) ) { aAdvSource.aStart.Set( theCol1,theRow1,theTab1 ); aAdvSource.aEnd.Set( theCol2,theRow2,theTab2 ); ((ScDBData*)pItems[i])->SetAdvancedQuerySource( &aAdvSource ); bDoUpdate = sal_True; // DBData is modified } } ((ScDBData*)pItems[i])->SetModified(bDoUpdate); //! Testen, ob mitten aus dem Bereich geloescht/eingefuegt wurde !!! } } void ScDBCollection::UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos ) { // wenn nOldPos vor nNewPos liegt, ist nNewPos schon angepasst for (sal_uInt16 i=0; iGetArea( aRange ); SCTAB nTab = aRange.aStart.Tab(); // hat nur eine Tabelle // anpassen wie die aktuelle Tabelle bei ScTablesHint (tabvwsh5.cxx) if ( nTab == nOldPos ) // verschobene Tabelle nTab = nNewPos; else if ( nOldPos < nNewPos ) // nach hinten verschoben { if ( nTab > nOldPos && nTab <= nNewPos ) // nachrueckender Bereich --nTab; } else // nach vorne verschoben { if ( nTab >= nNewPos && nTab < nOldPos ) // nachrueckender Bereich ++nTab; } sal_Bool bChanged = ( nTab != aRange.aStart.Tab() ); if (bChanged) pData->SetArea( nTab, aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Col(),aRange.aEnd .Row() ); // MoveTo ist nicht noetig, wenn nur die Tabelle geaendert ist pData->SetModified(bChanged); } } ScDBData* ScDBCollection::FindIndex(sal_uInt16 nIndex) { sal_uInt16 i = 0; while (i < nCount) { if ((*this)[i]->GetIndex() == nIndex) return (*this)[i]; i++; } return NULL; } sal_Bool ScDBCollection::Insert(ScDataObject* pScDataObject) { ScDBData* pData = (ScDBData*) pScDataObject; if (!pData->GetIndex()) // schon gesetzt? pData->SetIndex(nEntryIndex++); sal_Bool bInserted = ScSortedCollection::Insert(pScDataObject); if ( bInserted && pData->HasImportParam() && !pData->HasImportSelection() ) { pData->SetRefreshHandler( GetRefreshHandler() ); pData->SetRefreshControl( pDoc->GetRefreshTimerControlAddress() ); } return bInserted; } String ScDBCollection::GetNewDefaultDBName() { String aNoName = String::CreateFromAscii(SC_DBNAME_UNNAMED); String aNewName; unsigned short nDummy; int i = 1; do { aNewName = aNoName; aNewName += String::CreateFromInt32( i++ ); }while(SearchName(aNewName,nDummy)); return aNewName; } /* sal_Bool ScDBCollection::IsFiltered(SCTAB nTab, SCROW nRow) { SCCOL nLastCol; SCROW nLastRow; pDoc->GetLastAttrCellArea(nTab, nLastCol, nLastRow); if ( pItems ) { for (unsigned short i = 0; i < nCount; i++) { ScDBData* pData = (ScDBData*)pItems[i]; if ( pData->nTable == nTab && pData->HasQueryParam() && pData->bQueryInplace ) if ( nRow >= (pData->nStartRow + (pData->HasHeader()?1:0)) && nRow <= pData->nEndRow && nRow <= nLastRow ) return sal_True; } } return sal_False; } */ ScDBData* ScDBCollection::GetDBAtTable(SCTAB nTab, ScGetDBMode eMode) const { ScDBData* pDataEmpty = NULL; if (pItems) { for (unsigned short i = 0; i < nCount; i++) { ScDBData* pDBTemp = (ScDBData*)pItems[i]; if ( pDBTemp->nTable == nTab ) //Sym2_7885 mod { sal_Bool bImport = pDBTemp->HasImportParam(); sal_Bool bFilter = pDBTemp->HasAutoFilter() || pDBTemp->HasQueryParam(); sal_Bool bSort = pDBTemp->HasSortParam(); sal_Bool bSubtotal = pDBTemp->HasSubTotalParam(); sal_Bool bAnyParam = bImport || bFilter || bSort || bSubtotal; if ( ((eMode == SC_DB_MAKE_SORT) && bSort && !bFilter) || //Sym2_7334 mod 20100420 ((eMode == SC_DB_MAKE_SUBTOTAL) && bSubtotal && !bFilter ) || ((eMode == SC_DB_MAKE_FILTER || eMode == SC_DB_OLD_FILTER) && bFilter ) ) { return pDBTemp; } else if ( pDBTemp->IsBuildin() && !bAnyParam ) //Sym2_7885 mod { pDataEmpty = pDBTemp; } } } } return pDataEmpty; }