1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_connectivity.hxx" 30*cdf0e10cSrcweir #include "calc/CTable.hxx" 31*cdf0e10cSrcweir #include <com/sun/star/sdbc/ColumnValue.hpp> 32*cdf0e10cSrcweir #include <com/sun/star/sdbc/DataType.hpp> 33*cdf0e10cSrcweir //#ifndef _COM_SUN_STAR_UCB_XCONTENTACCESS_HPP_ 34*cdf0e10cSrcweir //#include <com/sun/star/ucb/XContentAccess.hpp> 35*cdf0e10cSrcweir //#endif 36*cdf0e10cSrcweir #include <com/sun/star/sdbc/XRow.hpp> 37*cdf0e10cSrcweir #include <com/sun/star/sheet/XSpreadsheetDocument.hpp> 38*cdf0e10cSrcweir #include <com/sun/star/sheet/XSpreadsheet.hpp> 39*cdf0e10cSrcweir #include <com/sun/star/sheet/XCellRangeAddressable.hpp> 40*cdf0e10cSrcweir #include <com/sun/star/sheet/XCellRangesQuery.hpp> 41*cdf0e10cSrcweir #include <com/sun/star/sheet/XDatabaseRanges.hpp> 42*cdf0e10cSrcweir #include <com/sun/star/sheet/XDatabaseRange.hpp> 43*cdf0e10cSrcweir #include <com/sun/star/sheet/XCellRangeReferrer.hpp> 44*cdf0e10cSrcweir #include <com/sun/star/sheet/XUsedAreaCursor.hpp> 45*cdf0e10cSrcweir #include <com/sun/star/sheet/CellFlags.hpp> 46*cdf0e10cSrcweir #include <com/sun/star/sheet/FormulaResult.hpp> 47*cdf0e10cSrcweir #include <com/sun/star/util/NumberFormat.hpp> 48*cdf0e10cSrcweir #include <com/sun/star/util/XNumberFormatsSupplier.hpp> 49*cdf0e10cSrcweir #include <com/sun/star/text/XText.hpp> 50*cdf0e10cSrcweir #include <svl/converter.hxx> 51*cdf0e10cSrcweir #include "calc/CConnection.hxx" 52*cdf0e10cSrcweir #include "calc/CColumns.hxx" 53*cdf0e10cSrcweir #include "connectivity/sdbcx/VColumn.hxx" 54*cdf0e10cSrcweir #include <rtl/ustrbuf.hxx> 55*cdf0e10cSrcweir #include <osl/thread.h> 56*cdf0e10cSrcweir #include <tools/config.hxx> 57*cdf0e10cSrcweir #include <comphelper/sequence.hxx> 58*cdf0e10cSrcweir #include <svl/zforlist.hxx> 59*cdf0e10cSrcweir #include <rtl/math.hxx> 60*cdf0e10cSrcweir #include <comphelper/extract.hxx> 61*cdf0e10cSrcweir #include <connectivity/dbexception.hxx> 62*cdf0e10cSrcweir #include <connectivity/dbconversion.hxx> 63*cdf0e10cSrcweir #include <comphelper/types.hxx> 64*cdf0e10cSrcweir #include <rtl/logfile.hxx> 65*cdf0e10cSrcweir 66*cdf0e10cSrcweir using namespace connectivity; 67*cdf0e10cSrcweir using namespace connectivity::calc; 68*cdf0e10cSrcweir using namespace connectivity::file; 69*cdf0e10cSrcweir using namespace ::cppu; 70*cdf0e10cSrcweir using namespace ::dbtools; 71*cdf0e10cSrcweir using namespace ::com::sun::star::uno; 72*cdf0e10cSrcweir using namespace ::com::sun::star::beans; 73*cdf0e10cSrcweir using namespace ::com::sun::star::sdbcx; 74*cdf0e10cSrcweir using namespace ::com::sun::star::sdbc; 75*cdf0e10cSrcweir using namespace ::com::sun::star::container; 76*cdf0e10cSrcweir using namespace ::com::sun::star::lang; 77*cdf0e10cSrcweir using namespace ::com::sun::star::sheet; 78*cdf0e10cSrcweir using namespace ::com::sun::star::table; 79*cdf0e10cSrcweir using namespace ::com::sun::star::text; 80*cdf0e10cSrcweir using namespace ::com::sun::star::util; 81*cdf0e10cSrcweir 82*cdf0e10cSrcweir // ------------------------------------------------------------------------- 83*cdf0e10cSrcweir 84*cdf0e10cSrcweir void lcl_UpdateArea( const Reference<XCellRange>& xUsedRange, sal_Int32& rEndCol, sal_Int32& rEndRow ) 85*cdf0e10cSrcweir { 86*cdf0e10cSrcweir //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcTable::lcl_UpdateArea" ); 87*cdf0e10cSrcweir // update rEndCol, rEndRow if any non-empty cell in xUsedRange is right/below 88*cdf0e10cSrcweir 89*cdf0e10cSrcweir const Reference<XCellRangesQuery> xUsedQuery( xUsedRange, UNO_QUERY ); 90*cdf0e10cSrcweir if ( xUsedQuery.is() ) 91*cdf0e10cSrcweir { 92*cdf0e10cSrcweir const sal_Int16 nContentFlags = 93*cdf0e10cSrcweir CellFlags::STRING | CellFlags::VALUE | CellFlags::DATETIME | CellFlags::FORMULA | CellFlags::ANNOTATION; 94*cdf0e10cSrcweir 95*cdf0e10cSrcweir const Reference<XSheetCellRanges> xUsedRanges = xUsedQuery->queryContentCells( nContentFlags ); 96*cdf0e10cSrcweir const Sequence<CellRangeAddress> aAddresses = xUsedRanges->getRangeAddresses(); 97*cdf0e10cSrcweir 98*cdf0e10cSrcweir const sal_Int32 nCount = aAddresses.getLength(); 99*cdf0e10cSrcweir const CellRangeAddress* pData = aAddresses.getConstArray(); 100*cdf0e10cSrcweir for ( sal_Int32 i=0; i<nCount; i++ ) 101*cdf0e10cSrcweir { 102*cdf0e10cSrcweir rEndCol = pData[i].EndColumn > rEndCol ? pData[i].EndColumn : rEndCol; 103*cdf0e10cSrcweir rEndRow = pData[i].EndRow > rEndRow ? pData[i].EndRow : rEndRow; 104*cdf0e10cSrcweir } 105*cdf0e10cSrcweir } 106*cdf0e10cSrcweir } 107*cdf0e10cSrcweir 108*cdf0e10cSrcweir void lcl_GetDataArea( const Reference<XSpreadsheet>& xSheet, sal_Int32& rColumnCount, sal_Int32& rRowCount ) 109*cdf0e10cSrcweir { 110*cdf0e10cSrcweir //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcTable::lcl_GetDataArea" ); 111*cdf0e10cSrcweir Reference<XSheetCellCursor> xCursor = xSheet->createCursor(); 112*cdf0e10cSrcweir Reference<XCellRangeAddressable> xRange( xCursor, UNO_QUERY ); 113*cdf0e10cSrcweir if ( !xRange.is() ) 114*cdf0e10cSrcweir { 115*cdf0e10cSrcweir rColumnCount = rRowCount = 0; 116*cdf0e10cSrcweir return; 117*cdf0e10cSrcweir } 118*cdf0e10cSrcweir 119*cdf0e10cSrcweir // first find the contiguous cell area starting at A1 120*cdf0e10cSrcweir 121*cdf0e10cSrcweir xCursor->collapseToSize( 1, 1 ); // single (first) cell 122*cdf0e10cSrcweir xCursor->collapseToCurrentRegion(); // contiguous data area 123*cdf0e10cSrcweir 124*cdf0e10cSrcweir CellRangeAddress aRegionAddr = xRange->getRangeAddress(); 125*cdf0e10cSrcweir sal_Int32 nEndCol = aRegionAddr.EndColumn; 126*cdf0e10cSrcweir sal_Int32 nEndRow = aRegionAddr.EndRow; 127*cdf0e10cSrcweir 128*cdf0e10cSrcweir Reference<XUsedAreaCursor> xUsed( xCursor, UNO_QUERY ); 129*cdf0e10cSrcweir if ( xUsed.is() ) 130*cdf0e10cSrcweir { 131*cdf0e10cSrcweir // The used area from XUsedAreaCursor includes visible attributes. 132*cdf0e10cSrcweir // If the used area is larger than the contiguous cell area, find non-empty 133*cdf0e10cSrcweir // cells in that area. 134*cdf0e10cSrcweir 135*cdf0e10cSrcweir xUsed->gotoEndOfUsedArea( sal_False ); 136*cdf0e10cSrcweir CellRangeAddress aUsedAddr = xRange->getRangeAddress(); 137*cdf0e10cSrcweir 138*cdf0e10cSrcweir if ( aUsedAddr.EndColumn > aRegionAddr.EndColumn ) 139*cdf0e10cSrcweir { 140*cdf0e10cSrcweir Reference<XCellRange> xUsedRange = xSheet->getCellRangeByPosition( 141*cdf0e10cSrcweir aRegionAddr.EndColumn + 1, 0, aUsedAddr.EndColumn, aUsedAddr.EndRow ); 142*cdf0e10cSrcweir lcl_UpdateArea( xUsedRange, nEndCol, nEndRow ); 143*cdf0e10cSrcweir } 144*cdf0e10cSrcweir 145*cdf0e10cSrcweir if ( aUsedAddr.EndRow > aRegionAddr.EndRow ) 146*cdf0e10cSrcweir { 147*cdf0e10cSrcweir // only up to the last column of aRegionAddr, the other columns are handled above 148*cdf0e10cSrcweir Reference<XCellRange> xUsedRange = xSheet->getCellRangeByPosition( 149*cdf0e10cSrcweir 0, aRegionAddr.EndRow + 1, aRegionAddr.EndColumn, aUsedAddr.EndRow ); 150*cdf0e10cSrcweir lcl_UpdateArea( xUsedRange, nEndCol, nEndRow ); 151*cdf0e10cSrcweir } 152*cdf0e10cSrcweir } 153*cdf0e10cSrcweir 154*cdf0e10cSrcweir rColumnCount = nEndCol + 1; // number of columns 155*cdf0e10cSrcweir rRowCount = nEndRow; // first row (headers) is not counted 156*cdf0e10cSrcweir } 157*cdf0e10cSrcweir 158*cdf0e10cSrcweir CellContentType lcl_GetContentOrResultType( const Reference<XCell>& xCell ) 159*cdf0e10cSrcweir { 160*cdf0e10cSrcweir //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcTable::lcl_GetContentOrResultType" ); 161*cdf0e10cSrcweir CellContentType eCellType = xCell->getType(); 162*cdf0e10cSrcweir if ( eCellType == CellContentType_FORMULA ) 163*cdf0e10cSrcweir { 164*cdf0e10cSrcweir static const ::rtl::OUString s_sFormulaResultType(RTL_CONSTASCII_USTRINGPARAM("FormulaResultType")); 165*cdf0e10cSrcweir Reference<XPropertySet> xProp( xCell, UNO_QUERY ); 166*cdf0e10cSrcweir try 167*cdf0e10cSrcweir { 168*cdf0e10cSrcweir xProp->getPropertyValue( s_sFormulaResultType ) >>= eCellType; // type of formula result 169*cdf0e10cSrcweir } 170*cdf0e10cSrcweir catch (UnknownPropertyException&) 171*cdf0e10cSrcweir { 172*cdf0e10cSrcweir eCellType = CellContentType_VALUE; // if FormulaResultType property not available 173*cdf0e10cSrcweir } 174*cdf0e10cSrcweir } 175*cdf0e10cSrcweir return eCellType; 176*cdf0e10cSrcweir } 177*cdf0e10cSrcweir 178*cdf0e10cSrcweir Reference<XCell> lcl_GetUsedCell( const Reference<XSpreadsheet>& xSheet, sal_Int32 nDocColumn, sal_Int32 nDocRow ) 179*cdf0e10cSrcweir { 180*cdf0e10cSrcweir //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcTable::lcl_GetUsedCell" ); 181*cdf0e10cSrcweir Reference<XCell> xCell = xSheet->getCellByPosition( nDocColumn, nDocRow ); 182*cdf0e10cSrcweir if ( xCell.is() && xCell->getType() == CellContentType_EMPTY ) 183*cdf0e10cSrcweir { 184*cdf0e10cSrcweir // get first non-empty cell 185*cdf0e10cSrcweir 186*cdf0e10cSrcweir Reference<XCellRangeAddressable> xAddr( xSheet, UNO_QUERY ); 187*cdf0e10cSrcweir if (xAddr.is()) 188*cdf0e10cSrcweir { 189*cdf0e10cSrcweir CellRangeAddress aTotalRange = xAddr->getRangeAddress(); 190*cdf0e10cSrcweir sal_Int32 nLastRow = aTotalRange.EndRow; 191*cdf0e10cSrcweir Reference<XCellRangesQuery> xQuery( xSheet->getCellRangeByPosition( nDocColumn, nDocRow, nDocColumn, nLastRow ), UNO_QUERY ); 192*cdf0e10cSrcweir if (xQuery.is()) 193*cdf0e10cSrcweir { 194*cdf0e10cSrcweir // queryIntersection to get a ranges object 195*cdf0e10cSrcweir Reference<XSheetCellRanges> xRanges = xQuery->queryIntersection( aTotalRange ); 196*cdf0e10cSrcweir if (xRanges.is()) 197*cdf0e10cSrcweir { 198*cdf0e10cSrcweir Reference<XEnumerationAccess> xCells = xRanges->getCells(); 199*cdf0e10cSrcweir if (xCells.is()) 200*cdf0e10cSrcweir { 201*cdf0e10cSrcweir Reference<XEnumeration> xEnum = xCells->createEnumeration(); 202*cdf0e10cSrcweir if ( xEnum.is() && xEnum->hasMoreElements() ) 203*cdf0e10cSrcweir { 204*cdf0e10cSrcweir // get first non-empty cell from enumeration 205*cdf0e10cSrcweir xCell.set(xEnum->nextElement(),UNO_QUERY); 206*cdf0e10cSrcweir } 207*cdf0e10cSrcweir // otherwise, keep empty cell 208*cdf0e10cSrcweir } 209*cdf0e10cSrcweir } 210*cdf0e10cSrcweir } 211*cdf0e10cSrcweir } 212*cdf0e10cSrcweir } 213*cdf0e10cSrcweir return xCell; 214*cdf0e10cSrcweir } 215*cdf0e10cSrcweir 216*cdf0e10cSrcweir bool lcl_HasTextInColumn( const Reference<XSpreadsheet>& xSheet, sal_Int32 nDocColumn, sal_Int32 nDocRow ) 217*cdf0e10cSrcweir { 218*cdf0e10cSrcweir //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcTable::lcl_HasTextInColumn" ); 219*cdf0e10cSrcweir // look for any text cell or text result in the column 220*cdf0e10cSrcweir 221*cdf0e10cSrcweir Reference<XCellRangeAddressable> xAddr( xSheet, UNO_QUERY ); 222*cdf0e10cSrcweir if (xAddr.is()) 223*cdf0e10cSrcweir { 224*cdf0e10cSrcweir CellRangeAddress aTotalRange = xAddr->getRangeAddress(); 225*cdf0e10cSrcweir sal_Int32 nLastRow = aTotalRange.EndRow; 226*cdf0e10cSrcweir Reference<XCellRangesQuery> xQuery( xSheet->getCellRangeByPosition( nDocColumn, nDocRow, nDocColumn, nLastRow ), UNO_QUERY ); 227*cdf0e10cSrcweir if (xQuery.is()) 228*cdf0e10cSrcweir { 229*cdf0e10cSrcweir // are there text cells in the column? 230*cdf0e10cSrcweir Reference<XSheetCellRanges> xTextContent = xQuery->queryContentCells( CellFlags::STRING ); 231*cdf0e10cSrcweir if ( xTextContent.is() && xTextContent->hasElements() ) 232*cdf0e10cSrcweir return true; 233*cdf0e10cSrcweir 234*cdf0e10cSrcweir // are there formulas with text results in the column? 235*cdf0e10cSrcweir Reference<XSheetCellRanges> xTextFormula = xQuery->queryFormulaCells( FormulaResult::STRING ); 236*cdf0e10cSrcweir if ( xTextFormula.is() && xTextFormula->hasElements() ) 237*cdf0e10cSrcweir return true; 238*cdf0e10cSrcweir } 239*cdf0e10cSrcweir } 240*cdf0e10cSrcweir 241*cdf0e10cSrcweir return false; 242*cdf0e10cSrcweir } 243*cdf0e10cSrcweir 244*cdf0e10cSrcweir void lcl_GetColumnInfo( const Reference<XSpreadsheet>& xSheet, const Reference<XNumberFormats>& xFormats, 245*cdf0e10cSrcweir sal_Int32 nDocColumn, sal_Int32 nStartRow, sal_Bool bHasHeaders, 246*cdf0e10cSrcweir ::rtl::OUString& rName, sal_Int32& rDataType, sal_Bool& rCurrency ) 247*cdf0e10cSrcweir { 248*cdf0e10cSrcweir //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcTable::lcl_GetColumnInfo" ); 249*cdf0e10cSrcweir //! avoid duplicate field names 250*cdf0e10cSrcweir 251*cdf0e10cSrcweir // get column name from first row, if range contains headers 252*cdf0e10cSrcweir 253*cdf0e10cSrcweir if ( bHasHeaders ) 254*cdf0e10cSrcweir { 255*cdf0e10cSrcweir Reference<XText> xHeaderText( xSheet->getCellByPosition( nDocColumn, nStartRow ), UNO_QUERY ); 256*cdf0e10cSrcweir if ( xHeaderText.is() ) 257*cdf0e10cSrcweir rName = xHeaderText->getString(); 258*cdf0e10cSrcweir } 259*cdf0e10cSrcweir 260*cdf0e10cSrcweir // get column type from first data row 261*cdf0e10cSrcweir 262*cdf0e10cSrcweir sal_Int32 nDataRow = nStartRow; 263*cdf0e10cSrcweir if ( bHasHeaders ) 264*cdf0e10cSrcweir ++nDataRow; 265*cdf0e10cSrcweir Reference<XCell> xDataCell = lcl_GetUsedCell( xSheet, nDocColumn, nDataRow ); 266*cdf0e10cSrcweir 267*cdf0e10cSrcweir Reference<XPropertySet> xProp( xDataCell, UNO_QUERY ); 268*cdf0e10cSrcweir if ( xProp.is() ) 269*cdf0e10cSrcweir { 270*cdf0e10cSrcweir rCurrency = sal_False; // set to true for currency below 271*cdf0e10cSrcweir 272*cdf0e10cSrcweir const CellContentType eCellType = lcl_GetContentOrResultType( xDataCell ); 273*cdf0e10cSrcweir // #i35178# use "text" type if there is any text cell in the column 274*cdf0e10cSrcweir if ( eCellType == CellContentType_TEXT || lcl_HasTextInColumn( xSheet, nDocColumn, nDataRow ) ) 275*cdf0e10cSrcweir rDataType = DataType::VARCHAR; 276*cdf0e10cSrcweir else if ( eCellType == CellContentType_VALUE ) 277*cdf0e10cSrcweir { 278*cdf0e10cSrcweir // get number format to distinguish between different types 279*cdf0e10cSrcweir 280*cdf0e10cSrcweir sal_Int16 nNumType = NumberFormat::NUMBER; 281*cdf0e10cSrcweir try 282*cdf0e10cSrcweir { 283*cdf0e10cSrcweir static ::rtl::OUString s_NumberFormat(RTL_CONSTASCII_USTRINGPARAM("NumberFormat")); 284*cdf0e10cSrcweir sal_Int32 nKey = 0; 285*cdf0e10cSrcweir 286*cdf0e10cSrcweir if ( xProp->getPropertyValue( s_NumberFormat ) >>= nKey ) 287*cdf0e10cSrcweir { 288*cdf0e10cSrcweir const Reference<XPropertySet> xFormat = xFormats->getByKey( nKey ); 289*cdf0e10cSrcweir if ( xFormat.is() ) 290*cdf0e10cSrcweir { 291*cdf0e10cSrcweir xFormat->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE) ) >>= nNumType; 292*cdf0e10cSrcweir } 293*cdf0e10cSrcweir } 294*cdf0e10cSrcweir } 295*cdf0e10cSrcweir catch ( Exception& ) 296*cdf0e10cSrcweir { 297*cdf0e10cSrcweir } 298*cdf0e10cSrcweir 299*cdf0e10cSrcweir if ( nNumType & NumberFormat::TEXT ) 300*cdf0e10cSrcweir rDataType = DataType::VARCHAR; 301*cdf0e10cSrcweir else if ( nNumType & NumberFormat::NUMBER ) 302*cdf0e10cSrcweir rDataType = DataType::DECIMAL; 303*cdf0e10cSrcweir else if ( nNumType & NumberFormat::CURRENCY ) 304*cdf0e10cSrcweir { 305*cdf0e10cSrcweir rCurrency = sal_True; 306*cdf0e10cSrcweir rDataType = DataType::DECIMAL; 307*cdf0e10cSrcweir } 308*cdf0e10cSrcweir else if ( ( nNumType & NumberFormat::DATETIME ) == NumberFormat::DATETIME ) 309*cdf0e10cSrcweir { 310*cdf0e10cSrcweir // NumberFormat::DATETIME is DATE | TIME 311*cdf0e10cSrcweir rDataType = DataType::TIMESTAMP; 312*cdf0e10cSrcweir } 313*cdf0e10cSrcweir else if ( nNumType & NumberFormat::DATE ) 314*cdf0e10cSrcweir rDataType = DataType::DATE; 315*cdf0e10cSrcweir else if ( nNumType & NumberFormat::TIME ) 316*cdf0e10cSrcweir rDataType = DataType::TIME; 317*cdf0e10cSrcweir else if ( nNumType & NumberFormat::LOGICAL ) 318*cdf0e10cSrcweir rDataType = DataType::BIT; 319*cdf0e10cSrcweir else 320*cdf0e10cSrcweir rDataType = DataType::DECIMAL; 321*cdf0e10cSrcweir } 322*cdf0e10cSrcweir else 323*cdf0e10cSrcweir { 324*cdf0e10cSrcweir // whole column empty 325*cdf0e10cSrcweir rDataType = DataType::VARCHAR; 326*cdf0e10cSrcweir } 327*cdf0e10cSrcweir } 328*cdf0e10cSrcweir } 329*cdf0e10cSrcweir 330*cdf0e10cSrcweir // ------------------------------------------------------------------------- 331*cdf0e10cSrcweir 332*cdf0e10cSrcweir void lcl_SetValue( ORowSetValue& rValue, const Reference<XSpreadsheet>& xSheet, 333*cdf0e10cSrcweir sal_Int32 nStartCol, sal_Int32 nStartRow, sal_Bool bHasHeaders, 334*cdf0e10cSrcweir const ::Date& rNullDate, 335*cdf0e10cSrcweir sal_Int32 nDBRow, sal_Int32 nDBColumn, sal_Int32 nType ) 336*cdf0e10cSrcweir { 337*cdf0e10cSrcweir //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcTable::lcl_SetValue" ); 338*cdf0e10cSrcweir sal_Int32 nDocColumn = nStartCol + nDBColumn - 1; // database counts from 1 339*cdf0e10cSrcweir sal_Int32 nDocRow = nStartRow + nDBRow - 1; 340*cdf0e10cSrcweir if (bHasHeaders) 341*cdf0e10cSrcweir ++nDocRow; 342*cdf0e10cSrcweir 343*cdf0e10cSrcweir const Reference<XCell> xCell = xSheet->getCellByPosition( nDocColumn, nDocRow ); 344*cdf0e10cSrcweir if ( xCell.is() ) 345*cdf0e10cSrcweir { 346*cdf0e10cSrcweir CellContentType eCellType = lcl_GetContentOrResultType( xCell ); 347*cdf0e10cSrcweir switch (nType) 348*cdf0e10cSrcweir { 349*cdf0e10cSrcweir case DataType::VARCHAR: 350*cdf0e10cSrcweir if ( eCellType == CellContentType_EMPTY ) 351*cdf0e10cSrcweir rValue.setNull(); 352*cdf0e10cSrcweir else 353*cdf0e10cSrcweir { 354*cdf0e10cSrcweir // #i25840# still let Calc convert numbers to text 355*cdf0e10cSrcweir const Reference<XText> xText( xCell, UNO_QUERY ); 356*cdf0e10cSrcweir if ( xText.is() ) 357*cdf0e10cSrcweir rValue = xText->getString(); 358*cdf0e10cSrcweir } 359*cdf0e10cSrcweir break; 360*cdf0e10cSrcweir case DataType::DECIMAL: 361*cdf0e10cSrcweir if ( eCellType == CellContentType_VALUE ) 362*cdf0e10cSrcweir rValue = xCell->getValue(); // double 363*cdf0e10cSrcweir else 364*cdf0e10cSrcweir rValue.setNull(); 365*cdf0e10cSrcweir break; 366*cdf0e10cSrcweir case DataType::BIT: 367*cdf0e10cSrcweir if ( eCellType == CellContentType_VALUE ) 368*cdf0e10cSrcweir rValue = (sal_Bool)( xCell->getValue() != 0.0 ); 369*cdf0e10cSrcweir else 370*cdf0e10cSrcweir rValue.setNull(); 371*cdf0e10cSrcweir break; 372*cdf0e10cSrcweir case DataType::DATE: 373*cdf0e10cSrcweir if ( eCellType == CellContentType_VALUE ) 374*cdf0e10cSrcweir { 375*cdf0e10cSrcweir ::Date aDate( rNullDate ); 376*cdf0e10cSrcweir aDate += (long)::rtl::math::approxFloor( xCell->getValue() ); 377*cdf0e10cSrcweir ::com::sun::star::util::Date aDateStruct( aDate.GetDay(), aDate.GetMonth(), aDate.GetYear() ); 378*cdf0e10cSrcweir rValue = aDateStruct; 379*cdf0e10cSrcweir } 380*cdf0e10cSrcweir else 381*cdf0e10cSrcweir rValue.setNull(); 382*cdf0e10cSrcweir break; 383*cdf0e10cSrcweir case DataType::TIME: 384*cdf0e10cSrcweir if ( eCellType == CellContentType_VALUE ) 385*cdf0e10cSrcweir { 386*cdf0e10cSrcweir double fCellVal = xCell->getValue(); 387*cdf0e10cSrcweir double fTime = fCellVal - rtl::math::approxFloor( fCellVal ); 388*cdf0e10cSrcweir long nIntTime = (long)rtl::math::round( fTime * 8640000.0 ); 389*cdf0e10cSrcweir if ( nIntTime == 8640000 ) 390*cdf0e10cSrcweir nIntTime = 0; // 23:59:59.995 and above is 00:00:00.00 391*cdf0e10cSrcweir ::com::sun::star::util::Time aTime; 392*cdf0e10cSrcweir aTime.HundredthSeconds = (sal_uInt16)( nIntTime % 100 ); 393*cdf0e10cSrcweir nIntTime /= 100; 394*cdf0e10cSrcweir aTime.Seconds = (sal_uInt16)( nIntTime % 60 ); 395*cdf0e10cSrcweir nIntTime /= 60; 396*cdf0e10cSrcweir aTime.Minutes = (sal_uInt16)( nIntTime % 60 ); 397*cdf0e10cSrcweir nIntTime /= 60; 398*cdf0e10cSrcweir OSL_ENSURE( nIntTime < 24, "error in time calculation" ); 399*cdf0e10cSrcweir aTime.Hours = (sal_uInt16) nIntTime; 400*cdf0e10cSrcweir rValue = aTime; 401*cdf0e10cSrcweir } 402*cdf0e10cSrcweir else 403*cdf0e10cSrcweir rValue.setNull(); 404*cdf0e10cSrcweir break; 405*cdf0e10cSrcweir case DataType::TIMESTAMP: 406*cdf0e10cSrcweir if ( eCellType == CellContentType_VALUE ) 407*cdf0e10cSrcweir { 408*cdf0e10cSrcweir double fCellVal = xCell->getValue(); 409*cdf0e10cSrcweir double fDays = ::rtl::math::approxFloor( fCellVal ); 410*cdf0e10cSrcweir double fTime = fCellVal - fDays; 411*cdf0e10cSrcweir long nIntDays = (long)fDays; 412*cdf0e10cSrcweir long nIntTime = (long)::rtl::math::round( fTime * 8640000.0 ); 413*cdf0e10cSrcweir if ( nIntTime == 8640000 ) 414*cdf0e10cSrcweir { 415*cdf0e10cSrcweir nIntTime = 0; // 23:59:59.995 and above is 00:00:00.00 416*cdf0e10cSrcweir ++nIntDays; // (next day) 417*cdf0e10cSrcweir } 418*cdf0e10cSrcweir 419*cdf0e10cSrcweir ::com::sun::star::util::DateTime aDateTime; 420*cdf0e10cSrcweir 421*cdf0e10cSrcweir aDateTime.HundredthSeconds = (sal_uInt16)( nIntTime % 100 ); 422*cdf0e10cSrcweir nIntTime /= 100; 423*cdf0e10cSrcweir aDateTime.Seconds = (sal_uInt16)( nIntTime % 60 ); 424*cdf0e10cSrcweir nIntTime /= 60; 425*cdf0e10cSrcweir aDateTime.Minutes = (sal_uInt16)( nIntTime % 60 ); 426*cdf0e10cSrcweir nIntTime /= 60; 427*cdf0e10cSrcweir OSL_ENSURE( nIntTime < 24, "error in time calculation" ); 428*cdf0e10cSrcweir aDateTime.Hours = (sal_uInt16) nIntTime; 429*cdf0e10cSrcweir 430*cdf0e10cSrcweir ::Date aDate( rNullDate ); 431*cdf0e10cSrcweir aDate += nIntDays; 432*cdf0e10cSrcweir aDateTime.Day = aDate.GetDay(); 433*cdf0e10cSrcweir aDateTime.Month = aDate.GetMonth(); 434*cdf0e10cSrcweir aDateTime.Year = aDate.GetYear(); 435*cdf0e10cSrcweir 436*cdf0e10cSrcweir rValue = aDateTime; 437*cdf0e10cSrcweir } 438*cdf0e10cSrcweir else 439*cdf0e10cSrcweir rValue.setNull(); 440*cdf0e10cSrcweir break; 441*cdf0e10cSrcweir } // switch (nType) 442*cdf0e10cSrcweir } 443*cdf0e10cSrcweir 444*cdf0e10cSrcweir // rValue.setTypeKind(nType); 445*cdf0e10cSrcweir } 446*cdf0e10cSrcweir 447*cdf0e10cSrcweir // ------------------------------------------------------------------------- 448*cdf0e10cSrcweir 449*cdf0e10cSrcweir ::rtl::OUString lcl_GetColumnStr( sal_Int32 nColumn ) 450*cdf0e10cSrcweir { 451*cdf0e10cSrcweir //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcTable::lcl_GetColumnStr" ); 452*cdf0e10cSrcweir if ( nColumn < 26 ) 453*cdf0e10cSrcweir return ::rtl::OUString::valueOf( (sal_Unicode) ( 'A' + nColumn ) ); 454*cdf0e10cSrcweir else 455*cdf0e10cSrcweir { 456*cdf0e10cSrcweir ::rtl::OUStringBuffer aBuffer(2); 457*cdf0e10cSrcweir aBuffer.setLength( 2 ); 458*cdf0e10cSrcweir aBuffer.setCharAt( 0, (sal_Unicode) ( 'A' + ( nColumn / 26 ) - 1 ) ); 459*cdf0e10cSrcweir aBuffer.setCharAt( 1, (sal_Unicode) ( 'A' + ( nColumn % 26 ) ) ); 460*cdf0e10cSrcweir return aBuffer.makeStringAndClear(); 461*cdf0e10cSrcweir } 462*cdf0e10cSrcweir } 463*cdf0e10cSrcweir 464*cdf0e10cSrcweir void OCalcTable::fillColumns() 465*cdf0e10cSrcweir { 466*cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcTable::fillColumns" ); 467*cdf0e10cSrcweir if ( !m_xSheet.is() ) 468*cdf0e10cSrcweir throw SQLException(); 469*cdf0e10cSrcweir 470*cdf0e10cSrcweir String aStrFieldName; 471*cdf0e10cSrcweir aStrFieldName.AssignAscii("Column"); 472*cdf0e10cSrcweir ::rtl::OUString aTypeName; 473*cdf0e10cSrcweir ::comphelper::UStringMixEqual aCase(m_pConnection->getMetaData()->supportsMixedCaseQuotedIdentifiers()); 474*cdf0e10cSrcweir const sal_Bool bStoresMixedCaseQuotedIdentifiers = getConnection()->getMetaData()->supportsMixedCaseQuotedIdentifiers(); 475*cdf0e10cSrcweir 476*cdf0e10cSrcweir for (sal_Int32 i = 0; i < m_nDataCols; i++) 477*cdf0e10cSrcweir { 478*cdf0e10cSrcweir ::rtl::OUString aColumnName; 479*cdf0e10cSrcweir sal_Int32 eType = DataType::OTHER; 480*cdf0e10cSrcweir sal_Bool bCurrency = sal_False; 481*cdf0e10cSrcweir 482*cdf0e10cSrcweir lcl_GetColumnInfo( m_xSheet, m_xFormats, m_nStartCol + i, m_nStartRow, m_bHasHeaders, 483*cdf0e10cSrcweir aColumnName, eType, bCurrency ); 484*cdf0e10cSrcweir 485*cdf0e10cSrcweir if ( !aColumnName.getLength() ) 486*cdf0e10cSrcweir aColumnName = lcl_GetColumnStr( i ); 487*cdf0e10cSrcweir 488*cdf0e10cSrcweir sal_Int32 nPrecision = 0; //! ... 489*cdf0e10cSrcweir sal_Int32 nDecimals = 0; //! ... 490*cdf0e10cSrcweir 491*cdf0e10cSrcweir switch ( eType ) 492*cdf0e10cSrcweir { 493*cdf0e10cSrcweir case DataType::VARCHAR: 494*cdf0e10cSrcweir { 495*cdf0e10cSrcweir static const ::rtl::OUString s_sType(RTL_CONSTASCII_USTRINGPARAM("VARCHAR")); 496*cdf0e10cSrcweir aTypeName = s_sType; 497*cdf0e10cSrcweir } 498*cdf0e10cSrcweir break; 499*cdf0e10cSrcweir case DataType::DECIMAL: 500*cdf0e10cSrcweir aTypeName = ::rtl::OUString::createFromAscii("DECIMAL"); 501*cdf0e10cSrcweir break; 502*cdf0e10cSrcweir case DataType::BIT: 503*cdf0e10cSrcweir aTypeName = ::rtl::OUString::createFromAscii("BOOL"); 504*cdf0e10cSrcweir break; 505*cdf0e10cSrcweir case DataType::DATE: 506*cdf0e10cSrcweir aTypeName = ::rtl::OUString::createFromAscii("DATE"); 507*cdf0e10cSrcweir break; 508*cdf0e10cSrcweir case DataType::TIME: 509*cdf0e10cSrcweir aTypeName = ::rtl::OUString::createFromAscii("TIME"); 510*cdf0e10cSrcweir break; 511*cdf0e10cSrcweir case DataType::TIMESTAMP: 512*cdf0e10cSrcweir aTypeName = ::rtl::OUString::createFromAscii("TIMESTAMP"); 513*cdf0e10cSrcweir break; 514*cdf0e10cSrcweir default: 515*cdf0e10cSrcweir OSL_ASSERT("missing type name"); 516*cdf0e10cSrcweir aTypeName = ::rtl::OUString(); 517*cdf0e10cSrcweir } 518*cdf0e10cSrcweir 519*cdf0e10cSrcweir // check if the column name already exists 520*cdf0e10cSrcweir ::rtl::OUString aAlias = aColumnName; 521*cdf0e10cSrcweir OSQLColumns::Vector::const_iterator aFind = connectivity::find(m_aColumns->get().begin(),m_aColumns->get().end(),aAlias,aCase); 522*cdf0e10cSrcweir sal_Int32 nExprCnt = 0; 523*cdf0e10cSrcweir while(aFind != m_aColumns->get().end()) 524*cdf0e10cSrcweir { 525*cdf0e10cSrcweir (aAlias = aColumnName) += ::rtl::OUString::valueOf((sal_Int32)++nExprCnt); 526*cdf0e10cSrcweir aFind = connectivity::find(m_aColumns->get().begin(),m_aColumns->get().end(),aAlias,aCase); 527*cdf0e10cSrcweir } 528*cdf0e10cSrcweir 529*cdf0e10cSrcweir sdbcx::OColumn* pColumn = new sdbcx::OColumn( aAlias, aTypeName, ::rtl::OUString(),::rtl::OUString(), 530*cdf0e10cSrcweir ColumnValue::NULLABLE, nPrecision, nDecimals, 531*cdf0e10cSrcweir eType, sal_False, sal_False, bCurrency, 532*cdf0e10cSrcweir bStoresMixedCaseQuotedIdentifiers); 533*cdf0e10cSrcweir Reference< XPropertySet> xCol = pColumn; 534*cdf0e10cSrcweir m_aColumns->get().push_back(xCol); 535*cdf0e10cSrcweir m_aTypes.push_back(eType); 536*cdf0e10cSrcweir m_aPrecisions.push_back(nPrecision); 537*cdf0e10cSrcweir m_aScales.push_back(nDecimals); 538*cdf0e10cSrcweir } 539*cdf0e10cSrcweir } 540*cdf0e10cSrcweir 541*cdf0e10cSrcweir // ------------------------------------------------------------------------- 542*cdf0e10cSrcweir OCalcTable::OCalcTable(sdbcx::OCollection* _pTables,OCalcConnection* _pConnection, 543*cdf0e10cSrcweir const ::rtl::OUString& _Name, 544*cdf0e10cSrcweir const ::rtl::OUString& _Type, 545*cdf0e10cSrcweir const ::rtl::OUString& _Description , 546*cdf0e10cSrcweir const ::rtl::OUString& _SchemaName, 547*cdf0e10cSrcweir const ::rtl::OUString& _CatalogName 548*cdf0e10cSrcweir ) : OCalcTable_BASE(_pTables,_pConnection,_Name, 549*cdf0e10cSrcweir _Type, 550*cdf0e10cSrcweir _Description, 551*cdf0e10cSrcweir _SchemaName, 552*cdf0e10cSrcweir _CatalogName) 553*cdf0e10cSrcweir ,m_pConnection(_pConnection) 554*cdf0e10cSrcweir ,m_nStartCol(0) 555*cdf0e10cSrcweir ,m_nStartRow(0) 556*cdf0e10cSrcweir ,m_nDataCols(0) 557*cdf0e10cSrcweir ,m_nDataRows(0) 558*cdf0e10cSrcweir ,m_bHasHeaders(sal_False) 559*cdf0e10cSrcweir { 560*cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcTable::OCalcTable" ); 561*cdf0e10cSrcweir } 562*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 563*cdf0e10cSrcweir void OCalcTable::construct() 564*cdf0e10cSrcweir { 565*cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcTable::construct" ); 566*cdf0e10cSrcweir // get sheet object 567*cdf0e10cSrcweir Reference< XSpreadsheetDocument> xDoc = m_pConnection->acquireDoc(); 568*cdf0e10cSrcweir if (xDoc.is()) 569*cdf0e10cSrcweir { 570*cdf0e10cSrcweir Reference<XSpreadsheets> xSheets = xDoc->getSheets(); 571*cdf0e10cSrcweir if ( xSheets.is() && xSheets->hasByName( m_Name ) ) 572*cdf0e10cSrcweir { 573*cdf0e10cSrcweir m_xSheet.set(xSheets->getByName( m_Name ),UNO_QUERY); 574*cdf0e10cSrcweir if ( m_xSheet.is() ) 575*cdf0e10cSrcweir { 576*cdf0e10cSrcweir lcl_GetDataArea( m_xSheet, m_nDataCols, m_nDataRows ); 577*cdf0e10cSrcweir m_bHasHeaders = sal_True; 578*cdf0e10cSrcweir // whole sheet is always assumed to include a header row 579*cdf0e10cSrcweir } 580*cdf0e10cSrcweir } 581*cdf0e10cSrcweir else // no sheet -> try database range 582*cdf0e10cSrcweir { 583*cdf0e10cSrcweir Reference<XPropertySet> xDocProp( xDoc, UNO_QUERY ); 584*cdf0e10cSrcweir if ( xDocProp.is() ) 585*cdf0e10cSrcweir { 586*cdf0e10cSrcweir Reference<XDatabaseRanges> xRanges(xDocProp->getPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DatabaseRanges")) ),UNO_QUERY); 587*cdf0e10cSrcweir 588*cdf0e10cSrcweir if ( xRanges.is() && xRanges->hasByName( m_Name ) ) 589*cdf0e10cSrcweir { 590*cdf0e10cSrcweir Reference<XDatabaseRange> xDBRange(xRanges->getByName( m_Name ),UNO_QUERY); 591*cdf0e10cSrcweir Reference<XCellRangeReferrer> xRefer( xDBRange, UNO_QUERY ); 592*cdf0e10cSrcweir if ( xRefer.is() ) 593*cdf0e10cSrcweir { 594*cdf0e10cSrcweir // Header flag is always stored with database range 595*cdf0e10cSrcweir // Get flag from FilterDescriptor 596*cdf0e10cSrcweir 597*cdf0e10cSrcweir sal_Bool bRangeHeader = sal_True; 598*cdf0e10cSrcweir Reference<XPropertySet> xFiltProp( xDBRange->getFilterDescriptor(), UNO_QUERY ); 599*cdf0e10cSrcweir if ( xFiltProp.is() ) 600*cdf0e10cSrcweir xFiltProp->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ContainsHeader"))) >>= bRangeHeader; 601*cdf0e10cSrcweir 602*cdf0e10cSrcweir Reference<XSheetCellRange> xSheetRange( xRefer->getReferredCells(), UNO_QUERY ); 603*cdf0e10cSrcweir Reference<XCellRangeAddressable> xAddr( xSheetRange, UNO_QUERY ); 604*cdf0e10cSrcweir if ( xSheetRange.is() && xAddr.is() ) 605*cdf0e10cSrcweir { 606*cdf0e10cSrcweir m_xSheet = xSheetRange->getSpreadsheet(); 607*cdf0e10cSrcweir CellRangeAddress aRangeAddr = xAddr->getRangeAddress(); 608*cdf0e10cSrcweir m_nStartCol = aRangeAddr.StartColumn; 609*cdf0e10cSrcweir m_nStartRow = aRangeAddr.StartRow; 610*cdf0e10cSrcweir m_nDataCols = aRangeAddr.EndColumn - m_nStartCol + 1; 611*cdf0e10cSrcweir // m_nDataRows is excluding header row 612*cdf0e10cSrcweir m_nDataRows = aRangeAddr.EndRow - m_nStartRow; 613*cdf0e10cSrcweir if ( !bRangeHeader ) 614*cdf0e10cSrcweir { 615*cdf0e10cSrcweir // m_nDataRows counts the whole range 616*cdf0e10cSrcweir m_nDataRows += 1; 617*cdf0e10cSrcweir } 618*cdf0e10cSrcweir 619*cdf0e10cSrcweir m_bHasHeaders = bRangeHeader; 620*cdf0e10cSrcweir } 621*cdf0e10cSrcweir } 622*cdf0e10cSrcweir } 623*cdf0e10cSrcweir } 624*cdf0e10cSrcweir } 625*cdf0e10cSrcweir 626*cdf0e10cSrcweir Reference<XNumberFormatsSupplier> xSupp( xDoc, UNO_QUERY ); 627*cdf0e10cSrcweir if (xSupp.is()) 628*cdf0e10cSrcweir m_xFormats = xSupp->getNumberFormats(); 629*cdf0e10cSrcweir 630*cdf0e10cSrcweir Reference<XPropertySet> xProp( xDoc, UNO_QUERY ); 631*cdf0e10cSrcweir if (xProp.is()) 632*cdf0e10cSrcweir { 633*cdf0e10cSrcweir ::com::sun::star::util::Date aDateStruct; 634*cdf0e10cSrcweir if ( xProp->getPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("NullDate")) ) >>= aDateStruct ) 635*cdf0e10cSrcweir m_aNullDate = ::Date( aDateStruct.Day, aDateStruct.Month, aDateStruct.Year ); 636*cdf0e10cSrcweir } 637*cdf0e10cSrcweir } 638*cdf0e10cSrcweir 639*cdf0e10cSrcweir //! default if no null date available? 640*cdf0e10cSrcweir 641*cdf0e10cSrcweir fillColumns(); 642*cdf0e10cSrcweir 643*cdf0e10cSrcweir refreshColumns(); 644*cdf0e10cSrcweir } 645*cdf0e10cSrcweir // ------------------------------------------------------------------------- 646*cdf0e10cSrcweir void OCalcTable::refreshColumns() 647*cdf0e10cSrcweir { 648*cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcTable::refreshColumns" ); 649*cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex ); 650*cdf0e10cSrcweir 651*cdf0e10cSrcweir TStringVector aVector; 652*cdf0e10cSrcweir 653*cdf0e10cSrcweir OSQLColumns::Vector::const_iterator aEnd = m_aColumns->get().end(); 654*cdf0e10cSrcweir for(OSQLColumns::Vector::const_iterator aIter = m_aColumns->get().begin();aIter != aEnd;++aIter) 655*cdf0e10cSrcweir aVector.push_back(Reference< XNamed>(*aIter,UNO_QUERY)->getName()); 656*cdf0e10cSrcweir 657*cdf0e10cSrcweir if(m_pColumns) 658*cdf0e10cSrcweir m_pColumns->reFill(aVector); 659*cdf0e10cSrcweir else 660*cdf0e10cSrcweir m_pColumns = new OCalcColumns(this,m_aMutex,aVector); 661*cdf0e10cSrcweir } 662*cdf0e10cSrcweir // ------------------------------------------------------------------------- 663*cdf0e10cSrcweir void OCalcTable::refreshIndexes() 664*cdf0e10cSrcweir { 665*cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcTable::refreshIndexes" ); 666*cdf0e10cSrcweir // Calc table has no index 667*cdf0e10cSrcweir } 668*cdf0e10cSrcweir 669*cdf0e10cSrcweir // ------------------------------------------------------------------------- 670*cdf0e10cSrcweir void SAL_CALL OCalcTable::disposing(void) 671*cdf0e10cSrcweir { 672*cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcTable::disposing" ); 673*cdf0e10cSrcweir OFileTable::disposing(); 674*cdf0e10cSrcweir ::osl::MutexGuard aGuard(m_aMutex); 675*cdf0e10cSrcweir m_aColumns = NULL; 676*cdf0e10cSrcweir if ( m_pConnection ) 677*cdf0e10cSrcweir m_pConnection->releaseDoc(); 678*cdf0e10cSrcweir m_pConnection = NULL; 679*cdf0e10cSrcweir 680*cdf0e10cSrcweir } 681*cdf0e10cSrcweir // ------------------------------------------------------------------------- 682*cdf0e10cSrcweir Sequence< Type > SAL_CALL OCalcTable::getTypes( ) throw(RuntimeException) 683*cdf0e10cSrcweir { 684*cdf0e10cSrcweir //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcTable::getTypes" ); 685*cdf0e10cSrcweir Sequence< Type > aTypes = OTable_TYPEDEF::getTypes(); 686*cdf0e10cSrcweir ::std::vector<Type> aOwnTypes; 687*cdf0e10cSrcweir aOwnTypes.reserve(aTypes.getLength()); 688*cdf0e10cSrcweir 689*cdf0e10cSrcweir const Type* pBegin = aTypes.getConstArray(); 690*cdf0e10cSrcweir const Type* pEnd = pBegin + aTypes.getLength(); 691*cdf0e10cSrcweir for(;pBegin != pEnd;++pBegin) 692*cdf0e10cSrcweir { 693*cdf0e10cSrcweir if(!( *pBegin == ::getCppuType((const Reference<XKeysSupplier>*)0) || 694*cdf0e10cSrcweir *pBegin == ::getCppuType((const Reference<XIndexesSupplier>*)0) || 695*cdf0e10cSrcweir *pBegin == ::getCppuType((const Reference<XRename>*)0) || 696*cdf0e10cSrcweir *pBegin == ::getCppuType((const Reference<XAlterTable>*)0) || 697*cdf0e10cSrcweir *pBegin == ::getCppuType((const Reference<XDataDescriptorFactory>*)0))) 698*cdf0e10cSrcweir aOwnTypes.push_back(*pBegin); 699*cdf0e10cSrcweir } 700*cdf0e10cSrcweir aOwnTypes.push_back(::getCppuType( (const Reference< ::com::sun::star::lang::XUnoTunnel > *)0 )); 701*cdf0e10cSrcweir 702*cdf0e10cSrcweir const Type* pAttrs = aOwnTypes.empty() ? 0 : &aOwnTypes[0]; 703*cdf0e10cSrcweir return Sequence< Type >(pAttrs, aOwnTypes.size()); 704*cdf0e10cSrcweir } 705*cdf0e10cSrcweir 706*cdf0e10cSrcweir // ------------------------------------------------------------------------- 707*cdf0e10cSrcweir Any SAL_CALL OCalcTable::queryInterface( const Type & rType ) throw(RuntimeException) 708*cdf0e10cSrcweir { 709*cdf0e10cSrcweir if( rType == ::getCppuType((const Reference<XKeysSupplier>*)0) || 710*cdf0e10cSrcweir rType == ::getCppuType((const Reference<XIndexesSupplier>*)0) || 711*cdf0e10cSrcweir rType == ::getCppuType((const Reference<XRename>*)0) || 712*cdf0e10cSrcweir rType == ::getCppuType((const Reference<XAlterTable>*)0) || 713*cdf0e10cSrcweir rType == ::getCppuType((const Reference<XDataDescriptorFactory>*)0)) 714*cdf0e10cSrcweir return Any(); 715*cdf0e10cSrcweir 716*cdf0e10cSrcweir const Any aRet = ::cppu::queryInterface(rType,static_cast< ::com::sun::star::lang::XUnoTunnel*> (this)); 717*cdf0e10cSrcweir return aRet.hasValue() ? aRet : OTable_TYPEDEF::queryInterface(rType); 718*cdf0e10cSrcweir } 719*cdf0e10cSrcweir 720*cdf0e10cSrcweir //-------------------------------------------------------------------------- 721*cdf0e10cSrcweir Sequence< sal_Int8 > OCalcTable::getUnoTunnelImplementationId() 722*cdf0e10cSrcweir { 723*cdf0e10cSrcweir //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcTable::getUnoTunnelImplementationId" ); 724*cdf0e10cSrcweir static ::cppu::OImplementationId * pId = 0; 725*cdf0e10cSrcweir if (! pId) 726*cdf0e10cSrcweir { 727*cdf0e10cSrcweir ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); 728*cdf0e10cSrcweir if (! pId) 729*cdf0e10cSrcweir { 730*cdf0e10cSrcweir static ::cppu::OImplementationId aId; 731*cdf0e10cSrcweir pId = &aId; 732*cdf0e10cSrcweir } 733*cdf0e10cSrcweir } 734*cdf0e10cSrcweir return pId->getImplementationId(); 735*cdf0e10cSrcweir } 736*cdf0e10cSrcweir 737*cdf0e10cSrcweir // com::sun::star::lang::XUnoTunnel 738*cdf0e10cSrcweir //------------------------------------------------------------------ 739*cdf0e10cSrcweir sal_Int64 OCalcTable::getSomething( const Sequence< sal_Int8 > & rId ) throw (RuntimeException) 740*cdf0e10cSrcweir { 741*cdf0e10cSrcweir //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcTable::getSomething" ); 742*cdf0e10cSrcweir return (rId.getLength() == 16 && 0 == rtl_compareMemory(getUnoTunnelImplementationId().getConstArray(), rId.getConstArray(), 16 ) ) 743*cdf0e10cSrcweir ? reinterpret_cast< sal_Int64 >( this ) 744*cdf0e10cSrcweir : OCalcTable_BASE::getSomething(rId); 745*cdf0e10cSrcweir } 746*cdf0e10cSrcweir //------------------------------------------------------------------ 747*cdf0e10cSrcweir sal_Int32 OCalcTable::getCurrentLastPos() const 748*cdf0e10cSrcweir { 749*cdf0e10cSrcweir //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcTable::getCurrentLastPos" ); 750*cdf0e10cSrcweir return m_nDataRows; 751*cdf0e10cSrcweir } 752*cdf0e10cSrcweir //------------------------------------------------------------------ 753*cdf0e10cSrcweir sal_Bool OCalcTable::seekRow(IResultSetHelper::Movement eCursorPosition, sal_Int32 nOffset, sal_Int32& nCurPos) 754*cdf0e10cSrcweir { 755*cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcTable::seekRow" ); 756*cdf0e10cSrcweir // ---------------------------------------------------------- 757*cdf0e10cSrcweir // Positionierung vorbereiten: 758*cdf0e10cSrcweir 759*cdf0e10cSrcweir sal_uInt32 nNumberOfRecords = m_nDataRows; 760*cdf0e10cSrcweir sal_uInt32 nTempPos = m_nFilePos; 761*cdf0e10cSrcweir m_nFilePos = nCurPos; 762*cdf0e10cSrcweir 763*cdf0e10cSrcweir switch(eCursorPosition) 764*cdf0e10cSrcweir { 765*cdf0e10cSrcweir case IResultSetHelper::NEXT: 766*cdf0e10cSrcweir m_nFilePos++; 767*cdf0e10cSrcweir break; 768*cdf0e10cSrcweir case IResultSetHelper::PRIOR: 769*cdf0e10cSrcweir if (m_nFilePos > 0) 770*cdf0e10cSrcweir m_nFilePos--; 771*cdf0e10cSrcweir break; 772*cdf0e10cSrcweir case IResultSetHelper::FIRST: 773*cdf0e10cSrcweir m_nFilePos = 1; 774*cdf0e10cSrcweir break; 775*cdf0e10cSrcweir case IResultSetHelper::LAST: 776*cdf0e10cSrcweir m_nFilePos = nNumberOfRecords; 777*cdf0e10cSrcweir break; 778*cdf0e10cSrcweir case IResultSetHelper::RELATIVE: 779*cdf0e10cSrcweir m_nFilePos = (((sal_Int32)m_nFilePos) + nOffset < 0) ? 0L 780*cdf0e10cSrcweir : (sal_uInt32)(((sal_Int32)m_nFilePos) + nOffset); 781*cdf0e10cSrcweir break; 782*cdf0e10cSrcweir case IResultSetHelper::ABSOLUTE: 783*cdf0e10cSrcweir case IResultSetHelper::BOOKMARK: 784*cdf0e10cSrcweir m_nFilePos = (sal_uInt32)nOffset; 785*cdf0e10cSrcweir break; 786*cdf0e10cSrcweir } 787*cdf0e10cSrcweir 788*cdf0e10cSrcweir if (m_nFilePos > (sal_Int32)nNumberOfRecords) 789*cdf0e10cSrcweir m_nFilePos = (sal_Int32)nNumberOfRecords + 1; 790*cdf0e10cSrcweir 791*cdf0e10cSrcweir if (m_nFilePos == 0 || m_nFilePos == (sal_Int32)nNumberOfRecords + 1) 792*cdf0e10cSrcweir goto Error; 793*cdf0e10cSrcweir else 794*cdf0e10cSrcweir { 795*cdf0e10cSrcweir //! read buffer / setup row object etc? 796*cdf0e10cSrcweir } 797*cdf0e10cSrcweir goto End; 798*cdf0e10cSrcweir 799*cdf0e10cSrcweir Error: 800*cdf0e10cSrcweir switch(eCursorPosition) 801*cdf0e10cSrcweir { 802*cdf0e10cSrcweir case IResultSetHelper::PRIOR: 803*cdf0e10cSrcweir case IResultSetHelper::FIRST: 804*cdf0e10cSrcweir m_nFilePos = 0; 805*cdf0e10cSrcweir break; 806*cdf0e10cSrcweir case IResultSetHelper::LAST: 807*cdf0e10cSrcweir case IResultSetHelper::NEXT: 808*cdf0e10cSrcweir case IResultSetHelper::ABSOLUTE: 809*cdf0e10cSrcweir case IResultSetHelper::RELATIVE: 810*cdf0e10cSrcweir if (nOffset > 0) 811*cdf0e10cSrcweir m_nFilePos = nNumberOfRecords + 1; 812*cdf0e10cSrcweir else if (nOffset < 0) 813*cdf0e10cSrcweir m_nFilePos = 0; 814*cdf0e10cSrcweir break; 815*cdf0e10cSrcweir case IResultSetHelper::BOOKMARK: 816*cdf0e10cSrcweir m_nFilePos = nTempPos; // vorherige Position 817*cdf0e10cSrcweir } 818*cdf0e10cSrcweir // aStatus.Set(SDB_STAT_NO_DATA_FOUND); 819*cdf0e10cSrcweir return sal_False; 820*cdf0e10cSrcweir 821*cdf0e10cSrcweir End: 822*cdf0e10cSrcweir nCurPos = m_nFilePos; 823*cdf0e10cSrcweir return sal_True; 824*cdf0e10cSrcweir } 825*cdf0e10cSrcweir //------------------------------------------------------------------ 826*cdf0e10cSrcweir sal_Bool OCalcTable::fetchRow( OValueRefRow& _rRow, const OSQLColumns & _rCols, 827*cdf0e10cSrcweir sal_Bool _bUseTableDefs, sal_Bool bRetrieveData ) 828*cdf0e10cSrcweir { 829*cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcTable::fetchRow" ); 830*cdf0e10cSrcweir // read the bookmark 831*cdf0e10cSrcweir 832*cdf0e10cSrcweir sal_Bool bIsCurRecordDeleted = sal_False; 833*cdf0e10cSrcweir _rRow->setDeleted(bIsCurRecordDeleted); 834*cdf0e10cSrcweir *(_rRow->get())[0] = m_nFilePos; 835*cdf0e10cSrcweir 836*cdf0e10cSrcweir if (!bRetrieveData) 837*cdf0e10cSrcweir return sal_True; 838*cdf0e10cSrcweir 839*cdf0e10cSrcweir // fields 840*cdf0e10cSrcweir 841*cdf0e10cSrcweir OSQLColumns::Vector::const_iterator aIter = _rCols.get().begin(); 842*cdf0e10cSrcweir OSQLColumns::Vector::const_iterator aEnd = _rCols.get().end(); 843*cdf0e10cSrcweir const OValueRefVector::Vector::size_type nCount = _rRow->get().size(); 844*cdf0e10cSrcweir for (OValueRefVector::Vector::size_type i = 1; aIter != aEnd && i < nCount; 845*cdf0e10cSrcweir ++aIter, i++) 846*cdf0e10cSrcweir { 847*cdf0e10cSrcweir if ( (_rRow->get())[i]->isBound() ) 848*cdf0e10cSrcweir { 849*cdf0e10cSrcweir sal_Int32 nType = 0; 850*cdf0e10cSrcweir if ( _bUseTableDefs ) 851*cdf0e10cSrcweir nType = m_aTypes[i-1]; 852*cdf0e10cSrcweir else 853*cdf0e10cSrcweir (*aIter)->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE)) >>= nType; 854*cdf0e10cSrcweir 855*cdf0e10cSrcweir 856*cdf0e10cSrcweir lcl_SetValue( (_rRow->get())[i]->get(), m_xSheet, m_nStartCol, m_nStartRow, m_bHasHeaders, 857*cdf0e10cSrcweir m_aNullDate, m_nFilePos, i, nType ); 858*cdf0e10cSrcweir } 859*cdf0e10cSrcweir } 860*cdf0e10cSrcweir return sal_True; 861*cdf0e10cSrcweir } 862*cdf0e10cSrcweir // ------------------------------------------------------------------------- 863*cdf0e10cSrcweir void OCalcTable::FileClose() 864*cdf0e10cSrcweir { 865*cdf0e10cSrcweir RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "calc", "Ocke.Janssen@sun.com", "OCalcTable::FileClose" ); 866*cdf0e10cSrcweir ::osl::MutexGuard aGuard(m_aMutex); 867*cdf0e10cSrcweir 868*cdf0e10cSrcweir OCalcTable_BASE::FileClose(); 869*cdf0e10cSrcweir } 870*cdf0e10cSrcweir // ------------------------------------------------------------------------- 871*cdf0e10cSrcweir 872