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_sc.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir 32*cdf0e10cSrcweir 33*cdf0e10cSrcweir // INCLUDE --------------------------------------------------------------- 34*cdf0e10cSrcweir 35*cdf0e10cSrcweir #include <stdio.h> 36*cdf0e10cSrcweir #include <tools/urlobj.hxx> 37*cdf0e10cSrcweir #include <svl/converter.hxx> 38*cdf0e10cSrcweir #include <svl/zforlist.hxx> 39*cdf0e10cSrcweir #include <comphelper/types.hxx> 40*cdf0e10cSrcweir #include <ucbhelper/content.hxx> 41*cdf0e10cSrcweir #include <unotools/sharedunocomponent.hxx> 42*cdf0e10cSrcweir #include <comphelper/processfactory.hxx> 43*cdf0e10cSrcweir #include <svx/txenctab.hxx> 44*cdf0e10cSrcweir #include <svx/dbcharsethelper.hxx> 45*cdf0e10cSrcweir 46*cdf0e10cSrcweir #include <com/sun/star/sdb/CommandType.hpp> 47*cdf0e10cSrcweir #include <com/sun/star/sdbc/DataType.hpp> 48*cdf0e10cSrcweir #include <com/sun/star/sdbc/XConnection.hpp> 49*cdf0e10cSrcweir #include <com/sun/star/sdbc/XDriver.hpp> 50*cdf0e10cSrcweir #include <com/sun/star/sdbc/XDriverAccess.hpp> 51*cdf0e10cSrcweir #include <com/sun/star/sdbc/XDriverManager.hpp> 52*cdf0e10cSrcweir #include <com/sun/star/sdbc/XResultSetUpdate.hpp> 53*cdf0e10cSrcweir #include <com/sun/star/sdbc/XRow.hpp> 54*cdf0e10cSrcweir #include <com/sun/star/sdbc/XRowSet.hpp> 55*cdf0e10cSrcweir #include <com/sun/star/sdbc/XRowUpdate.hpp> 56*cdf0e10cSrcweir #include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp> 57*cdf0e10cSrcweir #include <com/sun/star/sdbcx/XAppend.hpp> 58*cdf0e10cSrcweir #include <com/sun/star/sdbcx/XColumnsSupplier.hpp> 59*cdf0e10cSrcweir #include <com/sun/star/sdbcx/XDataDefinitionSupplier.hpp> 60*cdf0e10cSrcweir #include <com/sun/star/sdbcx/XDataDescriptorFactory.hpp> 61*cdf0e10cSrcweir #include <com/sun/star/sdbcx/XTablesSupplier.hpp> 62*cdf0e10cSrcweir #include <com/sun/star/lang/XMultiServiceFactory.hpp> 63*cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp> 64*cdf0e10cSrcweir #include <com/sun/star/container/XEnumerationAccess.hpp> 65*cdf0e10cSrcweir #include <com/sun/star/lang/XComponent.hpp> 66*cdf0e10cSrcweir #include <com/sun/star/ucb/NameClash.hpp> 67*cdf0e10cSrcweir #include <com/sun/star/ucb/TransferInfo.hpp> 68*cdf0e10cSrcweir #include <com/sun/star/ucb/XCommandInfo.hpp> 69*cdf0e10cSrcweir 70*cdf0e10cSrcweir #include "scerrors.hxx" 71*cdf0e10cSrcweir #include "docsh.hxx" 72*cdf0e10cSrcweir #include "filter.hxx" 73*cdf0e10cSrcweir #include "progress.hxx" 74*cdf0e10cSrcweir #include "collect.hxx" 75*cdf0e10cSrcweir #include "cell.hxx" 76*cdf0e10cSrcweir #include "editutil.hxx" 77*cdf0e10cSrcweir #include "cellform.hxx" 78*cdf0e10cSrcweir #include "dbdocutl.hxx" 79*cdf0e10cSrcweir #include "dociter.hxx" 80*cdf0e10cSrcweir #include "globstr.hrc" 81*cdf0e10cSrcweir 82*cdf0e10cSrcweir using namespace com::sun::star; 83*cdf0e10cSrcweir 84*cdf0e10cSrcweir // ----------------------------------------------------------------------- 85*cdf0e10cSrcweir 86*cdf0e10cSrcweir #define SC_SERVICE_ROWSET "com.sun.star.sdb.RowSet" 87*cdf0e10cSrcweir #define SC_SERVICE_DRVMAN "com.sun.star.sdbc.DriverManager" 88*cdf0e10cSrcweir 89*cdf0e10cSrcweir //! move to a header file? 90*cdf0e10cSrcweir //#define SC_DBPROP_DATASOURCENAME "DataSourceName" 91*cdf0e10cSrcweir #define SC_DBPROP_ACTIVECONNECTION "ActiveConnection" 92*cdf0e10cSrcweir #define SC_DBPROP_COMMAND "Command" 93*cdf0e10cSrcweir #define SC_DBPROP_COMMANDTYPE "CommandType" 94*cdf0e10cSrcweir 95*cdf0e10cSrcweir #define SC_DBPROP_NAME "Name" 96*cdf0e10cSrcweir #define SC_DBPROP_TYPE "Type" 97*cdf0e10cSrcweir #define SC_DBPROP_PRECISION "Precision" 98*cdf0e10cSrcweir #define SC_DBPROP_SCALE "Scale" 99*cdf0e10cSrcweir 100*cdf0e10cSrcweir #define SC_DBPROP_EXTENSION "Extension" 101*cdf0e10cSrcweir #define SC_DBPROP_CHARSET "CharSet" 102*cdf0e10cSrcweir 103*cdf0e10cSrcweir #define SC_ROWCOUNT_ERROR (-1) 104*cdf0e10cSrcweir 105*cdf0e10cSrcweir namespace 106*cdf0e10cSrcweir { 107*cdf0e10cSrcweir sal_uLong lcl_getDBaseConnection(uno::Reference<sdbc::XDriverManager>& _rDrvMgr,uno::Reference<sdbc::XConnection>& _rConnection,String& _rTabName,const String& rFullFileName,rtl_TextEncoding eCharSet) 108*cdf0e10cSrcweir { 109*cdf0e10cSrcweir INetURLObject aURL; 110*cdf0e10cSrcweir aURL.SetSmartProtocol( INET_PROT_FILE ); 111*cdf0e10cSrcweir aURL.SetSmartURL( rFullFileName ); 112*cdf0e10cSrcweir _rTabName = aURL.getBase( INetURLObject::LAST_SEGMENT, true, 113*cdf0e10cSrcweir INetURLObject::DECODE_UNAMBIGUOUS ); 114*cdf0e10cSrcweir String aExtension = aURL.getExtension(); 115*cdf0e10cSrcweir aURL.removeSegment(); 116*cdf0e10cSrcweir aURL.removeFinalSlash(); 117*cdf0e10cSrcweir String aPath = aURL.GetMainURL(INetURLObject::NO_DECODE); 118*cdf0e10cSrcweir uno::Reference<lang::XMultiServiceFactory> xFactory = comphelper::getProcessServiceFactory(); 119*cdf0e10cSrcweir if (!xFactory.is()) return SCERR_EXPORT_CONNECT; 120*cdf0e10cSrcweir 121*cdf0e10cSrcweir _rDrvMgr.set( xFactory->createInstance( 122*cdf0e10cSrcweir rtl::OUString::createFromAscii( SC_SERVICE_DRVMAN ) ), 123*cdf0e10cSrcweir uno::UNO_QUERY); 124*cdf0e10cSrcweir DBG_ASSERT( _rDrvMgr.is(), "can't get DriverManager" ); 125*cdf0e10cSrcweir if (!_rDrvMgr.is()) return SCERR_EXPORT_CONNECT; 126*cdf0e10cSrcweir 127*cdf0e10cSrcweir // get connection 128*cdf0e10cSrcweir 129*cdf0e10cSrcweir String aConnUrl = String::CreateFromAscii("sdbc:dbase:"); 130*cdf0e10cSrcweir aConnUrl += aPath; 131*cdf0e10cSrcweir 132*cdf0e10cSrcweir svxform::ODataAccessCharsetHelper aHelper; 133*cdf0e10cSrcweir ::std::vector< rtl_TextEncoding > aEncodings; 134*cdf0e10cSrcweir aHelper.getSupportedTextEncodings( aEncodings ); 135*cdf0e10cSrcweir ::std::vector< rtl_TextEncoding >::iterator aIter = ::std::find(aEncodings.begin(),aEncodings.end(),(rtl_TextEncoding) eCharSet); 136*cdf0e10cSrcweir if ( aIter == aEncodings.end() ) 137*cdf0e10cSrcweir { 138*cdf0e10cSrcweir DBG_ERRORFILE( "DBaseImport: dbtools::OCharsetMap doesn't know text encoding" ); 139*cdf0e10cSrcweir return SCERR_IMPORT_CONNECT; 140*cdf0e10cSrcweir } // if ( aIter == aMap.end() ) 141*cdf0e10cSrcweir rtl::OUString aCharSetStr; 142*cdf0e10cSrcweir if ( RTL_TEXTENCODING_DONTKNOW != *aIter ) 143*cdf0e10cSrcweir { // it's not the virtual "system charset" 144*cdf0e10cSrcweir const char* pIanaName = rtl_getMimeCharsetFromTextEncoding( *aIter ); 145*cdf0e10cSrcweir OSL_ENSURE( pIanaName, "invalid mime name!" ); 146*cdf0e10cSrcweir if ( pIanaName ) 147*cdf0e10cSrcweir aCharSetStr = ::rtl::OUString::createFromAscii( pIanaName ); 148*cdf0e10cSrcweir } 149*cdf0e10cSrcweir 150*cdf0e10cSrcweir uno::Sequence<beans::PropertyValue> aProps(2); 151*cdf0e10cSrcweir aProps[0].Name = rtl::OUString::createFromAscii(SC_DBPROP_EXTENSION); 152*cdf0e10cSrcweir aProps[0].Value <<= rtl::OUString( aExtension ); 153*cdf0e10cSrcweir aProps[1].Name = rtl::OUString::createFromAscii(SC_DBPROP_CHARSET); 154*cdf0e10cSrcweir aProps[1].Value <<= aCharSetStr; 155*cdf0e10cSrcweir 156*cdf0e10cSrcweir _rConnection = _rDrvMgr->getConnectionWithInfo( aConnUrl, aProps ); 157*cdf0e10cSrcweir return 0L; 158*cdf0e10cSrcweir } 159*cdf0e10cSrcweir } 160*cdf0e10cSrcweir // ----------------------------------------------------------------------- 161*cdf0e10cSrcweir // MoveFile/KillFile/IsDocument: similar to SfxContentHelper 162*cdf0e10cSrcweir 163*cdf0e10cSrcweir // static 164*cdf0e10cSrcweir sal_Bool ScDocShell::MoveFile( const INetURLObject& rSourceObj, const INetURLObject& rDestObj ) 165*cdf0e10cSrcweir { 166*cdf0e10cSrcweir sal_Bool bMoveData = sal_True; 167*cdf0e10cSrcweir sal_Bool bRet = sal_True, bKillSource = sal_False; 168*cdf0e10cSrcweir if ( rSourceObj.GetProtocol() != rDestObj.GetProtocol() ) 169*cdf0e10cSrcweir { 170*cdf0e10cSrcweir bMoveData = sal_False; 171*cdf0e10cSrcweir bKillSource = sal_True; 172*cdf0e10cSrcweir } 173*cdf0e10cSrcweir String aName = rDestObj.getName(); 174*cdf0e10cSrcweir INetURLObject aDestPathObj = rDestObj; 175*cdf0e10cSrcweir aDestPathObj.removeSegment(); 176*cdf0e10cSrcweir aDestPathObj.setFinalSlash(); 177*cdf0e10cSrcweir 178*cdf0e10cSrcweir try 179*cdf0e10cSrcweir { 180*cdf0e10cSrcweir ::ucbhelper::Content aDestPath( aDestPathObj.GetMainURL(INetURLObject::NO_DECODE), 181*cdf0e10cSrcweir uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > () ); 182*cdf0e10cSrcweir uno::Reference< ::com::sun::star::ucb::XCommandInfo > xInfo = aDestPath.getCommands(); 183*cdf0e10cSrcweir rtl::OUString aTransferName = rtl::OUString::createFromAscii( "transfer" ); 184*cdf0e10cSrcweir if ( xInfo->hasCommandByName( aTransferName ) ) 185*cdf0e10cSrcweir { 186*cdf0e10cSrcweir aDestPath.executeCommand( aTransferName, uno::makeAny( 187*cdf0e10cSrcweir ::com::sun::star::ucb::TransferInfo( bMoveData, rSourceObj.GetMainURL(INetURLObject::NO_DECODE), aName, 188*cdf0e10cSrcweir ::com::sun::star::ucb::NameClash::ERROR ) ) ); 189*cdf0e10cSrcweir } 190*cdf0e10cSrcweir else 191*cdf0e10cSrcweir { 192*cdf0e10cSrcweir DBG_ERRORFILE( "transfer command not available" ); 193*cdf0e10cSrcweir } 194*cdf0e10cSrcweir } 195*cdf0e10cSrcweir catch( uno::Exception& ) 196*cdf0e10cSrcweir { 197*cdf0e10cSrcweir // ucb may throw different exceptions on failure now 198*cdf0e10cSrcweir bRet = sal_False; 199*cdf0e10cSrcweir } 200*cdf0e10cSrcweir 201*cdf0e10cSrcweir if ( bKillSource ) 202*cdf0e10cSrcweir KillFile( rSourceObj ); 203*cdf0e10cSrcweir 204*cdf0e10cSrcweir return bRet; 205*cdf0e10cSrcweir } 206*cdf0e10cSrcweir 207*cdf0e10cSrcweir 208*cdf0e10cSrcweir // static 209*cdf0e10cSrcweir sal_Bool ScDocShell::KillFile( const INetURLObject& rURL ) 210*cdf0e10cSrcweir { 211*cdf0e10cSrcweir sal_Bool bRet = sal_True; 212*cdf0e10cSrcweir try 213*cdf0e10cSrcweir { 214*cdf0e10cSrcweir ::ucbhelper::Content aCnt( rURL.GetMainURL(INetURLObject::NO_DECODE), 215*cdf0e10cSrcweir uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > () ); 216*cdf0e10cSrcweir aCnt.executeCommand( rtl::OUString::createFromAscii( "delete" ), 217*cdf0e10cSrcweir comphelper::makeBoolAny( sal_True ) ); 218*cdf0e10cSrcweir } 219*cdf0e10cSrcweir catch( uno::Exception& ) 220*cdf0e10cSrcweir { 221*cdf0e10cSrcweir // ucb may throw different exceptions on failure now 222*cdf0e10cSrcweir bRet = sal_False; 223*cdf0e10cSrcweir } 224*cdf0e10cSrcweir 225*cdf0e10cSrcweir return bRet; 226*cdf0e10cSrcweir } 227*cdf0e10cSrcweir 228*cdf0e10cSrcweir // static 229*cdf0e10cSrcweir sal_Bool ScDocShell::IsDocument( const INetURLObject& rURL ) 230*cdf0e10cSrcweir { 231*cdf0e10cSrcweir sal_Bool bRet = sal_False; 232*cdf0e10cSrcweir try 233*cdf0e10cSrcweir { 234*cdf0e10cSrcweir ::ucbhelper::Content aCnt( rURL.GetMainURL(INetURLObject::NO_DECODE), 235*cdf0e10cSrcweir uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > () ); 236*cdf0e10cSrcweir bRet = aCnt.isDocument(); 237*cdf0e10cSrcweir } 238*cdf0e10cSrcweir catch( uno::Exception& ) 239*cdf0e10cSrcweir { 240*cdf0e10cSrcweir // ucb may throw different exceptions on failure now - warning only 241*cdf0e10cSrcweir DBG_WARNING( "Any other exception" ); 242*cdf0e10cSrcweir } 243*cdf0e10cSrcweir 244*cdf0e10cSrcweir return bRet; 245*cdf0e10cSrcweir } 246*cdf0e10cSrcweir 247*cdf0e10cSrcweir // ----------------------------------------------------------------------- 248*cdf0e10cSrcweir 249*cdf0e10cSrcweir sal_uLong ScDocShell::DBaseImport( const String& rFullFileName, CharSet eCharSet, 250*cdf0e10cSrcweir sal_Bool bSimpleColWidth[MAXCOLCOUNT] ) 251*cdf0e10cSrcweir { 252*cdf0e10cSrcweir sal_uLong nErr = eERR_OK; 253*cdf0e10cSrcweir long i; 254*cdf0e10cSrcweir long nColCount = 0; 255*cdf0e10cSrcweir 256*cdf0e10cSrcweir try 257*cdf0e10cSrcweir { 258*cdf0e10cSrcweir String aTabName; 259*cdf0e10cSrcweir uno::Reference<sdbc::XDriverManager> xDrvMan; 260*cdf0e10cSrcweir uno::Reference<sdbc::XConnection> xConnection; 261*cdf0e10cSrcweir sal_uLong nRet = lcl_getDBaseConnection(xDrvMan,xConnection,aTabName,rFullFileName,eCharSet); 262*cdf0e10cSrcweir if ( !xConnection.is() || !xDrvMan.is() ) 263*cdf0e10cSrcweir return nRet; 264*cdf0e10cSrcweir ::utl::DisposableComponent aConnectionHelper(xConnection); 265*cdf0e10cSrcweir 266*cdf0e10cSrcweir ScProgress aProgress( this, ScGlobal::GetRscString( STR_LOAD_DOC ), 0 ); 267*cdf0e10cSrcweir uno::Reference<lang::XMultiServiceFactory> xFactory = comphelper::getProcessServiceFactory(); 268*cdf0e10cSrcweir uno::Reference<sdbc::XRowSet> xRowSet( xFactory->createInstance( 269*cdf0e10cSrcweir rtl::OUString::createFromAscii( SC_SERVICE_ROWSET ) ), 270*cdf0e10cSrcweir uno::UNO_QUERY); 271*cdf0e10cSrcweir ::utl::DisposableComponent aRowSetHelper(xRowSet); 272*cdf0e10cSrcweir uno::Reference<beans::XPropertySet> xRowProp( xRowSet, uno::UNO_QUERY ); 273*cdf0e10cSrcweir DBG_ASSERT( xRowProp.is(), "can't get RowSet" ); 274*cdf0e10cSrcweir if (!xRowProp.is()) return SCERR_IMPORT_CONNECT; 275*cdf0e10cSrcweir 276*cdf0e10cSrcweir sal_Int32 nType = sdb::CommandType::TABLE; 277*cdf0e10cSrcweir uno::Any aAny; 278*cdf0e10cSrcweir 279*cdf0e10cSrcweir aAny <<= xConnection; 280*cdf0e10cSrcweir xRowProp->setPropertyValue( 281*cdf0e10cSrcweir rtl::OUString::createFromAscii(SC_DBPROP_ACTIVECONNECTION), aAny ); 282*cdf0e10cSrcweir 283*cdf0e10cSrcweir aAny <<= nType; 284*cdf0e10cSrcweir xRowProp->setPropertyValue( 285*cdf0e10cSrcweir rtl::OUString::createFromAscii(SC_DBPROP_COMMANDTYPE), aAny ); 286*cdf0e10cSrcweir 287*cdf0e10cSrcweir aAny <<= rtl::OUString( aTabName ); 288*cdf0e10cSrcweir xRowProp->setPropertyValue( 289*cdf0e10cSrcweir rtl::OUString::createFromAscii(SC_DBPROP_COMMAND), aAny ); 290*cdf0e10cSrcweir 291*cdf0e10cSrcweir xRowSet->execute(); 292*cdf0e10cSrcweir 293*cdf0e10cSrcweir uno::Reference<sdbc::XResultSetMetaData> xMeta; 294*cdf0e10cSrcweir uno::Reference<sdbc::XResultSetMetaDataSupplier> xMetaSupp( xRowSet, uno::UNO_QUERY ); 295*cdf0e10cSrcweir if ( xMetaSupp.is() ) 296*cdf0e10cSrcweir xMeta = xMetaSupp->getMetaData(); 297*cdf0e10cSrcweir if ( xMeta.is() ) 298*cdf0e10cSrcweir nColCount = xMeta->getColumnCount(); // this is the number of real columns 299*cdf0e10cSrcweir 300*cdf0e10cSrcweir if ( nColCount > MAXCOL+1 ) 301*cdf0e10cSrcweir { 302*cdf0e10cSrcweir nColCount = MAXCOL+1; 303*cdf0e10cSrcweir nErr = SCWARN_IMPORT_RANGE_OVERFLOW; // warning 304*cdf0e10cSrcweir } 305*cdf0e10cSrcweir 306*cdf0e10cSrcweir uno::Reference<sdbc::XRow> xRow( xRowSet, uno::UNO_QUERY ); 307*cdf0e10cSrcweir DBG_ASSERT( xRow.is(), "can't get Row" ); 308*cdf0e10cSrcweir if (!xRow.is()) return SCERR_IMPORT_CONNECT; 309*cdf0e10cSrcweir 310*cdf0e10cSrcweir // currency flag is not needed for dBase 311*cdf0e10cSrcweir uno::Sequence<sal_Int32> aColTypes( nColCount ); // column types 312*cdf0e10cSrcweir sal_Int32* pTypeArr = aColTypes.getArray(); 313*cdf0e10cSrcweir for (i=0; i<nColCount; i++) 314*cdf0e10cSrcweir pTypeArr[i] = xMeta->getColumnType( i+1 ); 315*cdf0e10cSrcweir 316*cdf0e10cSrcweir // read column names 317*cdf0e10cSrcweir //! add type descriptions 318*cdf0e10cSrcweir 319*cdf0e10cSrcweir aProgress.SetState( 0 ); 320*cdf0e10cSrcweir ScColumn::bDoubleAlloc = sal_True; // row count isn't readily available in advance 321*cdf0e10cSrcweir 322*cdf0e10cSrcweir for (i=0; i<nColCount; i++) 323*cdf0e10cSrcweir { 324*cdf0e10cSrcweir String aHeader = xMeta->getColumnLabel( i+1 ); 325*cdf0e10cSrcweir 326*cdf0e10cSrcweir switch ( pTypeArr[i] ) 327*cdf0e10cSrcweir { 328*cdf0e10cSrcweir case sdbc::DataType::BIT: 329*cdf0e10cSrcweir aHeader.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ",L" )); 330*cdf0e10cSrcweir break; 331*cdf0e10cSrcweir case sdbc::DataType::DATE: 332*cdf0e10cSrcweir aHeader.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ",D" )); 333*cdf0e10cSrcweir break; 334*cdf0e10cSrcweir case sdbc::DataType::LONGVARCHAR: 335*cdf0e10cSrcweir aHeader.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ",M" )); 336*cdf0e10cSrcweir break; 337*cdf0e10cSrcweir case sdbc::DataType::VARCHAR: 338*cdf0e10cSrcweir aHeader.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ",C," )); 339*cdf0e10cSrcweir aHeader += String::CreateFromInt32( xMeta->getColumnDisplaySize( i+1 ) ); 340*cdf0e10cSrcweir break; 341*cdf0e10cSrcweir case sdbc::DataType::DECIMAL: 342*cdf0e10cSrcweir { 343*cdf0e10cSrcweir long nPrec = xMeta->getPrecision( i+1 ); 344*cdf0e10cSrcweir long nScale = xMeta->getScale( i+1 ); 345*cdf0e10cSrcweir aHeader.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ",N," )); 346*cdf0e10cSrcweir aHeader += String::CreateFromInt32( 347*cdf0e10cSrcweir SvDbaseConverter::ConvertPrecisionToDbase( 348*cdf0e10cSrcweir nPrec, nScale ) ); 349*cdf0e10cSrcweir aHeader += ','; 350*cdf0e10cSrcweir aHeader += String::CreateFromInt32( nScale ); 351*cdf0e10cSrcweir } 352*cdf0e10cSrcweir break; 353*cdf0e10cSrcweir } 354*cdf0e10cSrcweir 355*cdf0e10cSrcweir aDocument.SetString( static_cast<SCCOL>(i), 0, 0, aHeader ); 356*cdf0e10cSrcweir } 357*cdf0e10cSrcweir 358*cdf0e10cSrcweir SCROW nRow = 1; // 0 is column titles 359*cdf0e10cSrcweir sal_Bool bEnd = sal_False; 360*cdf0e10cSrcweir while ( !bEnd && xRowSet->next() ) 361*cdf0e10cSrcweir { 362*cdf0e10cSrcweir if ( nRow <= MAXROW ) 363*cdf0e10cSrcweir { 364*cdf0e10cSrcweir SCCOL nCol = 0; 365*cdf0e10cSrcweir for (i=0; i<nColCount; i++) 366*cdf0e10cSrcweir { 367*cdf0e10cSrcweir ScDatabaseDocUtil::PutData( &aDocument, nCol, nRow, 0, 368*cdf0e10cSrcweir xRow, i+1, pTypeArr[i], sal_False, 369*cdf0e10cSrcweir &bSimpleColWidth[nCol] ); 370*cdf0e10cSrcweir ++nCol; 371*cdf0e10cSrcweir } 372*cdf0e10cSrcweir ++nRow; 373*cdf0e10cSrcweir } 374*cdf0e10cSrcweir else // past the end of the spreadsheet 375*cdf0e10cSrcweir { 376*cdf0e10cSrcweir bEnd = sal_True; // don't continue 377*cdf0e10cSrcweir nErr = SCWARN_IMPORT_RANGE_OVERFLOW; // warning message 378*cdf0e10cSrcweir } 379*cdf0e10cSrcweir } 380*cdf0e10cSrcweir } 381*cdf0e10cSrcweir catch ( sdbc::SQLException& ) 382*cdf0e10cSrcweir { 383*cdf0e10cSrcweir nErr = SCERR_IMPORT_CONNECT; 384*cdf0e10cSrcweir } 385*cdf0e10cSrcweir catch ( uno::Exception& ) 386*cdf0e10cSrcweir { 387*cdf0e10cSrcweir DBG_ERROR("Unexpected exception in database"); 388*cdf0e10cSrcweir nErr = ERRCODE_IO_GENERAL; 389*cdf0e10cSrcweir } 390*cdf0e10cSrcweir 391*cdf0e10cSrcweir ScColumn::bDoubleAlloc = sal_False; 392*cdf0e10cSrcweir if ( nColCount > 0 ) 393*cdf0e10cSrcweir aDocument.DoColResize( 0, 0, static_cast<SCCOL>(nColCount) - 1, 0 ); 394*cdf0e10cSrcweir 395*cdf0e10cSrcweir return nErr; 396*cdf0e10cSrcweir } 397*cdf0e10cSrcweir 398*cdf0e10cSrcweir // ----------------------------------------------------------------------- 399*cdf0e10cSrcweir 400*cdf0e10cSrcweir inline sal_Bool IsAsciiDigit( sal_Unicode c ) 401*cdf0e10cSrcweir { 402*cdf0e10cSrcweir return 0x30 <= c && c <= 0x39; 403*cdf0e10cSrcweir } 404*cdf0e10cSrcweir 405*cdf0e10cSrcweir inline sal_Bool IsAsciiAlpha( sal_Unicode c ) 406*cdf0e10cSrcweir { 407*cdf0e10cSrcweir return (0x41 <= c && c <= 0x5a) || (0x61 <= c && c <= 0x7a); 408*cdf0e10cSrcweir } 409*cdf0e10cSrcweir 410*cdf0e10cSrcweir void lcl_GetColumnTypes( ScDocShell& rDocShell, 411*cdf0e10cSrcweir const ScRange& rDataRange, sal_Bool bHasFieldNames, 412*cdf0e10cSrcweir rtl::OUString* pColNames, sal_Int32* pColTypes, 413*cdf0e10cSrcweir sal_Int32* pColLengths, sal_Int32* pColScales, 414*cdf0e10cSrcweir sal_Bool& bHasMemo, CharSet eCharSet ) 415*cdf0e10cSrcweir { 416*cdf0e10cSrcweir // updating of column titles didn't work in 5.2 and isn't always wanted 417*cdf0e10cSrcweir // (saving normally shouldn't modify the document) 418*cdf0e10cSrcweir //! read flag from configuration 419*cdf0e10cSrcweir sal_Bool bUpdateTitles = sal_False; 420*cdf0e10cSrcweir 421*cdf0e10cSrcweir ScDocument* pDoc = rDocShell.GetDocument(); 422*cdf0e10cSrcweir SvNumberFormatter* pNumFmt = pDoc->GetFormatTable(); 423*cdf0e10cSrcweir 424*cdf0e10cSrcweir SCTAB nTab = rDataRange.aStart.Tab(); 425*cdf0e10cSrcweir SCCOL nFirstCol = rDataRange.aStart.Col(); 426*cdf0e10cSrcweir SCROW nFirstRow = rDataRange.aStart.Row(); 427*cdf0e10cSrcweir SCCOL nLastCol = rDataRange.aEnd.Col(); 428*cdf0e10cSrcweir SCROW nLastRow = rDataRange.aEnd.Row(); 429*cdf0e10cSrcweir 430*cdf0e10cSrcweir ScStrCollection aFieldNamesCollection; 431*cdf0e10cSrcweir 432*cdf0e10cSrcweir long nField = 0; 433*cdf0e10cSrcweir SCROW nFirstDataRow = ( bHasFieldNames ? nFirstRow + 1 : nFirstRow ); 434*cdf0e10cSrcweir for ( SCCOL nCol = nFirstCol; nCol <= nLastCol; nCol++ ) 435*cdf0e10cSrcweir { 436*cdf0e10cSrcweir sal_Bool bTypeDefined = sal_False; 437*cdf0e10cSrcweir sal_Bool bPrecDefined = sal_False; 438*cdf0e10cSrcweir sal_Int32 nFieldLen = 0; 439*cdf0e10cSrcweir sal_Int32 nPrecision = 0; 440*cdf0e10cSrcweir sal_Int32 nDbType = sdbc::DataType::SQLNULL; 441*cdf0e10cSrcweir String aFieldName, aString; 442*cdf0e10cSrcweir 443*cdf0e10cSrcweir // Feldname[,Type[,Width[,Prec]]] 444*cdf0e10cSrcweir // Typ etc.: L; D; C[,W]; N[,W[,P]] 445*cdf0e10cSrcweir if ( bHasFieldNames ) 446*cdf0e10cSrcweir { 447*cdf0e10cSrcweir pDoc->GetString( nCol, nFirstRow, nTab, aString ); 448*cdf0e10cSrcweir aString.ToUpperAscii(); 449*cdf0e10cSrcweir xub_StrLen nToken = aString.GetTokenCount( ',' ); 450*cdf0e10cSrcweir if ( nToken > 1 ) 451*cdf0e10cSrcweir { 452*cdf0e10cSrcweir aFieldName = aString.GetToken( 0, ',' ); 453*cdf0e10cSrcweir aString.EraseAllChars( ' ' ); 454*cdf0e10cSrcweir switch ( aString.GetToken( 1, ',' ).GetChar(0) ) 455*cdf0e10cSrcweir { 456*cdf0e10cSrcweir case 'L' : 457*cdf0e10cSrcweir nDbType = sdbc::DataType::BIT; 458*cdf0e10cSrcweir nFieldLen = 1; 459*cdf0e10cSrcweir bTypeDefined = sal_True; 460*cdf0e10cSrcweir bPrecDefined = sal_True; 461*cdf0e10cSrcweir break; 462*cdf0e10cSrcweir case 'D' : 463*cdf0e10cSrcweir nDbType = sdbc::DataType::DATE; 464*cdf0e10cSrcweir nFieldLen = 8; 465*cdf0e10cSrcweir bTypeDefined = sal_True; 466*cdf0e10cSrcweir bPrecDefined = sal_True; 467*cdf0e10cSrcweir break; 468*cdf0e10cSrcweir case 'M' : 469*cdf0e10cSrcweir nDbType = sdbc::DataType::LONGVARCHAR; 470*cdf0e10cSrcweir nFieldLen = 10; 471*cdf0e10cSrcweir bTypeDefined = sal_True; 472*cdf0e10cSrcweir bPrecDefined = sal_True; 473*cdf0e10cSrcweir bHasMemo = sal_True; 474*cdf0e10cSrcweir break; 475*cdf0e10cSrcweir case 'C' : 476*cdf0e10cSrcweir nDbType = sdbc::DataType::VARCHAR; 477*cdf0e10cSrcweir bTypeDefined = sal_True; 478*cdf0e10cSrcweir bPrecDefined = sal_True; 479*cdf0e10cSrcweir break; 480*cdf0e10cSrcweir case 'N' : 481*cdf0e10cSrcweir nDbType = sdbc::DataType::DECIMAL; 482*cdf0e10cSrcweir bTypeDefined = sal_True; 483*cdf0e10cSrcweir break; 484*cdf0e10cSrcweir } 485*cdf0e10cSrcweir if ( bTypeDefined && !nFieldLen && nToken > 2 ) 486*cdf0e10cSrcweir { 487*cdf0e10cSrcweir nFieldLen = aString.GetToken( 2, ',' ).ToInt32(); 488*cdf0e10cSrcweir if ( !bPrecDefined && nToken > 3 ) 489*cdf0e10cSrcweir { 490*cdf0e10cSrcweir String aTmp( aString.GetToken( 3, ',' ) ); 491*cdf0e10cSrcweir if ( CharClass::isAsciiNumeric(aTmp) ) 492*cdf0e10cSrcweir { 493*cdf0e10cSrcweir nPrecision = aTmp.ToInt32(); 494*cdf0e10cSrcweir bPrecDefined = sal_True; 495*cdf0e10cSrcweir } 496*cdf0e10cSrcweir } 497*cdf0e10cSrcweir } 498*cdf0e10cSrcweir } 499*cdf0e10cSrcweir else 500*cdf0e10cSrcweir aFieldName = aString; 501*cdf0e10cSrcweir 502*cdf0e10cSrcweir // Feldnamen pruefen und ggbf. gueltigen Feldnamen erzeugen. 503*cdf0e10cSrcweir // Erstes Zeichen muss Buchstabe sein, 504*cdf0e10cSrcweir // weitere nur alphanumerisch und Unterstrich erlaubt, 505*cdf0e10cSrcweir // "_DBASELOCK" ist reserviert (obsolet weil erstes Zeichen kein Buchstabe), 506*cdf0e10cSrcweir // keine doppelten Namen. 507*cdf0e10cSrcweir if ( !IsAsciiAlpha( aFieldName.GetChar(0) ) ) 508*cdf0e10cSrcweir aFieldName.Insert( 'N', 0 ); 509*cdf0e10cSrcweir String aTmpStr; 510*cdf0e10cSrcweir sal_Unicode c; 511*cdf0e10cSrcweir for ( const sal_Unicode* p = aFieldName.GetBuffer(); ( c = *p ) != 0; p++ ) 512*cdf0e10cSrcweir { 513*cdf0e10cSrcweir if ( IsAsciiAlpha( c ) || IsAsciiDigit( c ) || c == '_' ) 514*cdf0e10cSrcweir aTmpStr += c; 515*cdf0e10cSrcweir else 516*cdf0e10cSrcweir aTmpStr += '_'; 517*cdf0e10cSrcweir } 518*cdf0e10cSrcweir aFieldName = aTmpStr; 519*cdf0e10cSrcweir if ( aFieldName.Len() > 10 ) 520*cdf0e10cSrcweir aFieldName.Erase( 10 ); 521*cdf0e10cSrcweir StrData* pStrData = new StrData( aFieldName ); 522*cdf0e10cSrcweir if ( !aFieldNamesCollection.Insert( pStrData ) ) 523*cdf0e10cSrcweir { // doppelter Feldname, numerisch erweitern 524*cdf0e10cSrcweir sal_uInt16 nSub = 1; 525*cdf0e10cSrcweir String aFixPart( aFieldName ); 526*cdf0e10cSrcweir do 527*cdf0e10cSrcweir { 528*cdf0e10cSrcweir ++nSub; 529*cdf0e10cSrcweir String aVarPart = String::CreateFromInt32( nSub ); 530*cdf0e10cSrcweir if ( aFixPart.Len() + aVarPart.Len() > 10 ) 531*cdf0e10cSrcweir aFixPart.Erase( 10 - aVarPart.Len() ); 532*cdf0e10cSrcweir aFieldName = aFixPart; 533*cdf0e10cSrcweir aFieldName += aVarPart; 534*cdf0e10cSrcweir pStrData->SetString( aFieldName ); 535*cdf0e10cSrcweir } while ( !aFieldNamesCollection.Insert( pStrData ) ); 536*cdf0e10cSrcweir } 537*cdf0e10cSrcweir } 538*cdf0e10cSrcweir else 539*cdf0e10cSrcweir { 540*cdf0e10cSrcweir aFieldName = 'N'; 541*cdf0e10cSrcweir aFieldName += String::CreateFromInt32(nCol+1); 542*cdf0e10cSrcweir } 543*cdf0e10cSrcweir 544*cdf0e10cSrcweir if ( !bTypeDefined ) 545*cdf0e10cSrcweir { // Feldtyp 546*cdf0e10cSrcweir ScBaseCell* pCell; 547*cdf0e10cSrcweir pDoc->GetCell( nCol, nFirstDataRow, nTab, pCell ); 548*cdf0e10cSrcweir if ( !pCell || pCell->HasStringData() ) 549*cdf0e10cSrcweir nDbType = sdbc::DataType::VARCHAR; 550*cdf0e10cSrcweir else 551*cdf0e10cSrcweir { 552*cdf0e10cSrcweir sal_uInt32 nFormat; 553*cdf0e10cSrcweir pDoc->GetNumberFormat( nCol, nFirstDataRow, nTab, nFormat ); 554*cdf0e10cSrcweir if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA 555*cdf0e10cSrcweir && ((nFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0) ) 556*cdf0e10cSrcweir { 557*cdf0e10cSrcweir nFormat = ScGlobal::GetStandardFormat( 558*cdf0e10cSrcweir ((ScFormulaCell*)pCell)->GetValue(), *pNumFmt, nFormat, 559*cdf0e10cSrcweir ((ScFormulaCell*)pCell)->GetFormatType() ); 560*cdf0e10cSrcweir } 561*cdf0e10cSrcweir switch ( pNumFmt->GetType( nFormat ) ) 562*cdf0e10cSrcweir { 563*cdf0e10cSrcweir case NUMBERFORMAT_LOGICAL : 564*cdf0e10cSrcweir nDbType = sdbc::DataType::BIT; 565*cdf0e10cSrcweir nFieldLen = 1; 566*cdf0e10cSrcweir break; 567*cdf0e10cSrcweir case NUMBERFORMAT_DATE : 568*cdf0e10cSrcweir nDbType = sdbc::DataType::DATE; 569*cdf0e10cSrcweir nFieldLen = 8; 570*cdf0e10cSrcweir break; 571*cdf0e10cSrcweir case NUMBERFORMAT_TIME : 572*cdf0e10cSrcweir case NUMBERFORMAT_DATETIME : 573*cdf0e10cSrcweir nDbType = sdbc::DataType::VARCHAR; 574*cdf0e10cSrcweir break; 575*cdf0e10cSrcweir default: 576*cdf0e10cSrcweir nDbType = sdbc::DataType::DECIMAL; 577*cdf0e10cSrcweir } 578*cdf0e10cSrcweir } 579*cdf0e10cSrcweir } 580*cdf0e10cSrcweir sal_Bool bSdbLenAdjusted = sal_False; 581*cdf0e10cSrcweir sal_Bool bSdbLenBad = sal_False; 582*cdf0e10cSrcweir // Feldlaenge 583*cdf0e10cSrcweir if ( nDbType == sdbc::DataType::VARCHAR && !nFieldLen ) 584*cdf0e10cSrcweir { // maximale Feldbreite bestimmen 585*cdf0e10cSrcweir nFieldLen = pDoc->GetMaxStringLen( nTab, nCol, nFirstDataRow, 586*cdf0e10cSrcweir nLastRow, eCharSet ); 587*cdf0e10cSrcweir if ( nFieldLen == 0 ) 588*cdf0e10cSrcweir nFieldLen = 1; 589*cdf0e10cSrcweir } 590*cdf0e10cSrcweir else if ( nDbType == sdbc::DataType::DECIMAL ) 591*cdf0e10cSrcweir { // maximale Feldbreite und Nachkommastellen bestimmen 592*cdf0e10cSrcweir xub_StrLen nLen; 593*cdf0e10cSrcweir sal_uInt16 nPrec; 594*cdf0e10cSrcweir nLen = pDoc->GetMaxNumberStringLen( nPrec, nTab, nCol, 595*cdf0e10cSrcweir nFirstDataRow, nLastRow ); 596*cdf0e10cSrcweir // dBaseIII Limit Nachkommastellen: 15 597*cdf0e10cSrcweir if ( nPrecision > 15 ) 598*cdf0e10cSrcweir nPrecision = 15; 599*cdf0e10cSrcweir if ( nPrec > 15 ) 600*cdf0e10cSrcweir nPrec = 15; 601*cdf0e10cSrcweir if ( bPrecDefined && nPrecision != nPrec ) 602*cdf0e10cSrcweir { // Laenge auf vorgegebene Nachkommastellen anpassen 603*cdf0e10cSrcweir if ( nPrecision ) 604*cdf0e10cSrcweir nLen = sal::static_int_cast<xub_StrLen>( nLen + ( nPrecision - nPrec ) ); 605*cdf0e10cSrcweir else 606*cdf0e10cSrcweir nLen -= nPrec+1; // auch den . mit raus 607*cdf0e10cSrcweir } 608*cdf0e10cSrcweir if ( nLen > nFieldLen && !bTypeDefined ) 609*cdf0e10cSrcweir nFieldLen = nLen; 610*cdf0e10cSrcweir if ( !bPrecDefined ) 611*cdf0e10cSrcweir nPrecision = nPrec; 612*cdf0e10cSrcweir if ( nFieldLen == 0 ) 613*cdf0e10cSrcweir nFieldLen = 1; 614*cdf0e10cSrcweir else if ( nFieldLen > 19 ) 615*cdf0e10cSrcweir nFieldLen = 19; // dBaseIII Limit Feldlaenge numerisch: 19 616*cdf0e10cSrcweir if ( nPrecision && nFieldLen < nPrecision + 2 ) 617*cdf0e10cSrcweir nFieldLen = nPrecision + 2; // 0. muss mit reinpassen 618*cdf0e10cSrcweir // 538 MUST: Sdb internal representation adds 2 to the field length! 619*cdf0e10cSrcweir // To give the user what he wants we must substract it here. 620*cdf0e10cSrcweir //! CAVEAT! There is no way to define a numeric field with a length 621*cdf0e10cSrcweir //! of 1 and no decimals! 622*cdf0e10cSrcweir if ( nFieldLen == 1 && nPrecision == 0 ) 623*cdf0e10cSrcweir bSdbLenBad = sal_True; 624*cdf0e10cSrcweir nFieldLen = SvDbaseConverter::ConvertPrecisionToOdbc( nFieldLen, nPrecision ); 625*cdf0e10cSrcweir bSdbLenAdjusted = sal_True; 626*cdf0e10cSrcweir } 627*cdf0e10cSrcweir if ( nFieldLen > 254 ) 628*cdf0e10cSrcweir { 629*cdf0e10cSrcweir if ( nDbType == sdbc::DataType::VARCHAR ) 630*cdf0e10cSrcweir { // zu lang fuer normales Textfeld => Memofeld 631*cdf0e10cSrcweir nDbType = sdbc::DataType::LONGVARCHAR; 632*cdf0e10cSrcweir nFieldLen = 10; 633*cdf0e10cSrcweir bHasMemo = sal_True; 634*cdf0e10cSrcweir } 635*cdf0e10cSrcweir else 636*cdf0e10cSrcweir nFieldLen = 254; // dumm gelaufen.. 637*cdf0e10cSrcweir } 638*cdf0e10cSrcweir 639*cdf0e10cSrcweir pColNames[nField] = aFieldName; 640*cdf0e10cSrcweir pColTypes[nField] = nDbType; 641*cdf0e10cSrcweir pColLengths[nField] = nFieldLen; 642*cdf0e10cSrcweir pColScales[nField] = nPrecision; 643*cdf0e10cSrcweir 644*cdf0e10cSrcweir // undo change to field length, reflect reality 645*cdf0e10cSrcweir if ( bSdbLenAdjusted ) 646*cdf0e10cSrcweir { 647*cdf0e10cSrcweir nFieldLen = SvDbaseConverter::ConvertPrecisionToDbase( nFieldLen, nPrecision ); 648*cdf0e10cSrcweir if ( bSdbLenBad && nFieldLen == 1 ) 649*cdf0e10cSrcweir nFieldLen = 2; // THIS is reality 650*cdf0e10cSrcweir } 651*cdf0e10cSrcweir if ( bUpdateTitles ) 652*cdf0e10cSrcweir { // Angabe anpassen und ausgeben 653*cdf0e10cSrcweir String aOutString = aFieldName; 654*cdf0e10cSrcweir switch ( nDbType ) 655*cdf0e10cSrcweir { 656*cdf0e10cSrcweir case sdbc::DataType::BIT : 657*cdf0e10cSrcweir aOutString.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ",L" )); 658*cdf0e10cSrcweir break; 659*cdf0e10cSrcweir case sdbc::DataType::DATE : 660*cdf0e10cSrcweir aOutString.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ",D" )); 661*cdf0e10cSrcweir break; 662*cdf0e10cSrcweir case sdbc::DataType::LONGVARCHAR : 663*cdf0e10cSrcweir aOutString.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ",M" )); 664*cdf0e10cSrcweir break; 665*cdf0e10cSrcweir case sdbc::DataType::VARCHAR : 666*cdf0e10cSrcweir aOutString.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ",C," )); 667*cdf0e10cSrcweir aOutString += String::CreateFromInt32( nFieldLen ); 668*cdf0e10cSrcweir break; 669*cdf0e10cSrcweir case sdbc::DataType::DECIMAL : 670*cdf0e10cSrcweir aOutString.AppendAscii(RTL_CONSTASCII_STRINGPARAM( ",N," )); 671*cdf0e10cSrcweir aOutString += String::CreateFromInt32( nFieldLen ); 672*cdf0e10cSrcweir aOutString += ','; 673*cdf0e10cSrcweir aOutString += String::CreateFromInt32( nPrecision ); 674*cdf0e10cSrcweir break; 675*cdf0e10cSrcweir } 676*cdf0e10cSrcweir if ( !aOutString.EqualsIgnoreCaseAscii( aString ) ) 677*cdf0e10cSrcweir { 678*cdf0e10cSrcweir pDoc->SetString( nCol, nFirstRow, nTab, aOutString ); 679*cdf0e10cSrcweir rDocShell.PostPaint( nCol, nFirstRow, nTab, nCol, nFirstRow, nTab, PAINT_GRID ); 680*cdf0e10cSrcweir } 681*cdf0e10cSrcweir } 682*cdf0e10cSrcweir ++nField; 683*cdf0e10cSrcweir } 684*cdf0e10cSrcweir } 685*cdf0e10cSrcweir 686*cdf0e10cSrcweir 687*cdf0e10cSrcweir inline void lcl_getLongVarCharEditString( String& rString, 688*cdf0e10cSrcweir const ScBaseCell* pCell, ScFieldEditEngine& rEditEngine ) 689*cdf0e10cSrcweir { 690*cdf0e10cSrcweir rEditEngine.SetText( *((const ScEditCell*)pCell)->GetData() ); 691*cdf0e10cSrcweir rString = rEditEngine.GetText( LINEEND_CRLF ); 692*cdf0e10cSrcweir } 693*cdf0e10cSrcweir 694*cdf0e10cSrcweir inline void lcl_getLongVarCharString( String& rString, ScBaseCell* pCell, 695*cdf0e10cSrcweir ScDocument& rDocument, SCCOL nCol, SCROW nRow, SCTAB nTab, 696*cdf0e10cSrcweir SvNumberFormatter& rNumFmt ) 697*cdf0e10cSrcweir { 698*cdf0e10cSrcweir sal_uInt32 nFormat; 699*cdf0e10cSrcweir Color* pColor; 700*cdf0e10cSrcweir rDocument.GetNumberFormat( nCol, nRow, nTab, nFormat ); 701*cdf0e10cSrcweir ScCellFormat::GetString( pCell, nFormat, rString, &pColor, rNumFmt ); 702*cdf0e10cSrcweir } 703*cdf0e10cSrcweir 704*cdf0e10cSrcweir 705*cdf0e10cSrcweir sal_uLong ScDocShell::DBaseExport( const String& rFullFileName, CharSet eCharSet, sal_Bool& bHasMemo ) 706*cdf0e10cSrcweir { 707*cdf0e10cSrcweir // remove the file so the dBase driver doesn't find an invalid file 708*cdf0e10cSrcweir INetURLObject aDeleteObj( rFullFileName, INET_PROT_FILE ); 709*cdf0e10cSrcweir KillFile( aDeleteObj ); 710*cdf0e10cSrcweir 711*cdf0e10cSrcweir sal_uLong nErr = eERR_OK; 712*cdf0e10cSrcweir uno::Any aAny; 713*cdf0e10cSrcweir 714*cdf0e10cSrcweir SCCOL nFirstCol, nLastCol; 715*cdf0e10cSrcweir SCROW nFirstRow, nLastRow; 716*cdf0e10cSrcweir SCTAB nTab = GetSaveTab(); 717*cdf0e10cSrcweir aDocument.GetDataStart( nTab, nFirstCol, nFirstRow ); 718*cdf0e10cSrcweir aDocument.GetCellArea( nTab, nLastCol, nLastRow ); 719*cdf0e10cSrcweir if ( nFirstCol > nLastCol ) 720*cdf0e10cSrcweir nFirstCol = nLastCol; 721*cdf0e10cSrcweir if ( nFirstRow > nLastRow ) 722*cdf0e10cSrcweir nFirstRow = nLastRow; 723*cdf0e10cSrcweir ScProgress aProgress( this, ScGlobal::GetRscString( STR_SAVE_DOC ), 724*cdf0e10cSrcweir nLastRow - nFirstRow ); 725*cdf0e10cSrcweir SvNumberFormatter* pNumFmt = aDocument.GetFormatTable(); 726*cdf0e10cSrcweir 727*cdf0e10cSrcweir sal_Bool bHasFieldNames = sal_True; 728*cdf0e10cSrcweir for ( SCCOL nDocCol = nFirstCol; nDocCol <= nLastCol && bHasFieldNames; nDocCol++ ) 729*cdf0e10cSrcweir { // nur Strings in erster Zeile => sind Feldnamen 730*cdf0e10cSrcweir if ( !aDocument.HasStringData( nDocCol, nFirstRow, nTab ) ) 731*cdf0e10cSrcweir bHasFieldNames = sal_False; 732*cdf0e10cSrcweir } 733*cdf0e10cSrcweir 734*cdf0e10cSrcweir long nColCount = nLastCol - nFirstCol + 1; 735*cdf0e10cSrcweir uno::Sequence<rtl::OUString> aColNames( nColCount ); 736*cdf0e10cSrcweir uno::Sequence<sal_Int32> aColTypes( nColCount ); 737*cdf0e10cSrcweir uno::Sequence<sal_Int32> aColLengths( nColCount ); 738*cdf0e10cSrcweir uno::Sequence<sal_Int32> aColScales( nColCount ); 739*cdf0e10cSrcweir 740*cdf0e10cSrcweir ScRange aDataRange( nFirstCol, nFirstRow, nTab, nLastCol, nLastRow, nTab ); 741*cdf0e10cSrcweir lcl_GetColumnTypes( *this, aDataRange, bHasFieldNames, 742*cdf0e10cSrcweir aColNames.getArray(), aColTypes.getArray(), 743*cdf0e10cSrcweir aColLengths.getArray(), aColScales.getArray(), 744*cdf0e10cSrcweir bHasMemo, eCharSet ); 745*cdf0e10cSrcweir // also needed for exception catch 746*cdf0e10cSrcweir SCROW nDocRow = 0; 747*cdf0e10cSrcweir ScFieldEditEngine aEditEngine( aDocument.GetEditPool() ); 748*cdf0e10cSrcweir String aString; 749*cdf0e10cSrcweir String aTabName; 750*cdf0e10cSrcweir 751*cdf0e10cSrcweir try 752*cdf0e10cSrcweir { 753*cdf0e10cSrcweir uno::Reference<sdbc::XDriverManager> xDrvMan; 754*cdf0e10cSrcweir uno::Reference<sdbc::XConnection> xConnection; 755*cdf0e10cSrcweir sal_uLong nRet = lcl_getDBaseConnection(xDrvMan,xConnection,aTabName,rFullFileName,eCharSet); 756*cdf0e10cSrcweir if ( !xConnection.is() || !xDrvMan.is() ) 757*cdf0e10cSrcweir return nRet; 758*cdf0e10cSrcweir ::utl::DisposableComponent aConnectionHelper(xConnection); 759*cdf0e10cSrcweir 760*cdf0e10cSrcweir // get dBase driver 761*cdf0e10cSrcweir uno::Reference< sdbc::XDriverAccess> xAccess(xDrvMan,uno::UNO_QUERY); 762*cdf0e10cSrcweir uno::Reference< sdbcx::XDataDefinitionSupplier > xDDSup( xAccess->getDriverByURL( xConnection->getMetaData()->getURL() ), uno::UNO_QUERY ); 763*cdf0e10cSrcweir if ( !xDDSup.is() ) 764*cdf0e10cSrcweir return SCERR_EXPORT_CONNECT; 765*cdf0e10cSrcweir 766*cdf0e10cSrcweir // create table 767*cdf0e10cSrcweir uno::Reference<sdbcx::XTablesSupplier> xTablesSupp =xDDSup->getDataDefinitionByConnection( xConnection ); 768*cdf0e10cSrcweir DBG_ASSERT( xTablesSupp.is(), "can't get Data Definition" ); 769*cdf0e10cSrcweir if (!xTablesSupp.is()) return SCERR_EXPORT_CONNECT; 770*cdf0e10cSrcweir 771*cdf0e10cSrcweir uno::Reference<container::XNameAccess> xTables = xTablesSupp->getTables(); 772*cdf0e10cSrcweir DBG_ASSERT( xTables.is(), "can't get Tables" ); 773*cdf0e10cSrcweir if (!xTables.is()) return SCERR_EXPORT_CONNECT; 774*cdf0e10cSrcweir 775*cdf0e10cSrcweir uno::Reference<sdbcx::XDataDescriptorFactory> xTablesFact( xTables, uno::UNO_QUERY ); 776*cdf0e10cSrcweir DBG_ASSERT( xTablesFact.is(), "can't get tables factory" ); 777*cdf0e10cSrcweir if (!xTablesFact.is()) return SCERR_EXPORT_CONNECT; 778*cdf0e10cSrcweir 779*cdf0e10cSrcweir uno::Reference<sdbcx::XAppend> xTablesAppend( xTables, uno::UNO_QUERY ); 780*cdf0e10cSrcweir DBG_ASSERT( xTablesAppend.is(), "can't get tables XAppend" ); 781*cdf0e10cSrcweir if (!xTablesAppend.is()) return SCERR_EXPORT_CONNECT; 782*cdf0e10cSrcweir 783*cdf0e10cSrcweir uno::Reference<beans::XPropertySet> xTableDesc = xTablesFact->createDataDescriptor(); 784*cdf0e10cSrcweir DBG_ASSERT( xTableDesc.is(), "can't get table descriptor" ); 785*cdf0e10cSrcweir if (!xTableDesc.is()) return SCERR_EXPORT_CONNECT; 786*cdf0e10cSrcweir 787*cdf0e10cSrcweir aAny <<= rtl::OUString( aTabName ); 788*cdf0e10cSrcweir xTableDesc->setPropertyValue( rtl::OUString::createFromAscii(SC_DBPROP_NAME), aAny ); 789*cdf0e10cSrcweir 790*cdf0e10cSrcweir // create columns 791*cdf0e10cSrcweir 792*cdf0e10cSrcweir uno::Reference<sdbcx::XColumnsSupplier> xColumnsSupp( xTableDesc, uno::UNO_QUERY ); 793*cdf0e10cSrcweir DBG_ASSERT( xColumnsSupp.is(), "can't get columns supplier" ); 794*cdf0e10cSrcweir if (!xColumnsSupp.is()) return SCERR_EXPORT_CONNECT; 795*cdf0e10cSrcweir 796*cdf0e10cSrcweir uno::Reference<container::XNameAccess> xColumns = xColumnsSupp->getColumns(); 797*cdf0e10cSrcweir DBG_ASSERT( xColumns.is(), "can't get columns" ); 798*cdf0e10cSrcweir if (!xColumns.is()) return SCERR_EXPORT_CONNECT; 799*cdf0e10cSrcweir 800*cdf0e10cSrcweir uno::Reference<sdbcx::XDataDescriptorFactory> xColumnsFact( xColumns, uno::UNO_QUERY ); 801*cdf0e10cSrcweir DBG_ASSERT( xColumnsFact.is(), "can't get columns factory" ); 802*cdf0e10cSrcweir if (!xColumnsFact.is()) return SCERR_EXPORT_CONNECT; 803*cdf0e10cSrcweir 804*cdf0e10cSrcweir uno::Reference<sdbcx::XAppend> xColumnsAppend( xColumns, uno::UNO_QUERY ); 805*cdf0e10cSrcweir DBG_ASSERT( xColumnsAppend.is(), "can't get columns XAppend" ); 806*cdf0e10cSrcweir if (!xColumnsAppend.is()) return SCERR_EXPORT_CONNECT; 807*cdf0e10cSrcweir 808*cdf0e10cSrcweir const rtl::OUString* pColNames = aColNames.getConstArray(); 809*cdf0e10cSrcweir const sal_Int32* pColTypes = aColTypes.getConstArray(); 810*cdf0e10cSrcweir const sal_Int32* pColLengths = aColLengths.getConstArray(); 811*cdf0e10cSrcweir const sal_Int32* pColScales = aColScales.getConstArray(); 812*cdf0e10cSrcweir long nCol; 813*cdf0e10cSrcweir 814*cdf0e10cSrcweir for (nCol=0; nCol<nColCount; nCol++) 815*cdf0e10cSrcweir { 816*cdf0e10cSrcweir uno::Reference<beans::XPropertySet> xColumnDesc = xColumnsFact->createDataDescriptor(); 817*cdf0e10cSrcweir DBG_ASSERT( xColumnDesc.is(), "can't get column descriptor" ); 818*cdf0e10cSrcweir if (!xColumnDesc.is()) return SCERR_EXPORT_CONNECT; 819*cdf0e10cSrcweir 820*cdf0e10cSrcweir aAny <<= pColNames[nCol]; 821*cdf0e10cSrcweir xColumnDesc->setPropertyValue( rtl::OUString::createFromAscii(SC_DBPROP_NAME), aAny ); 822*cdf0e10cSrcweir 823*cdf0e10cSrcweir aAny <<= pColTypes[nCol]; 824*cdf0e10cSrcweir xColumnDesc->setPropertyValue( rtl::OUString::createFromAscii(SC_DBPROP_TYPE), aAny ); 825*cdf0e10cSrcweir 826*cdf0e10cSrcweir aAny <<= pColLengths[nCol]; 827*cdf0e10cSrcweir xColumnDesc->setPropertyValue( rtl::OUString::createFromAscii(SC_DBPROP_PRECISION), aAny ); 828*cdf0e10cSrcweir 829*cdf0e10cSrcweir aAny <<= pColScales[nCol]; 830*cdf0e10cSrcweir xColumnDesc->setPropertyValue( rtl::OUString::createFromAscii(SC_DBPROP_SCALE), aAny ); 831*cdf0e10cSrcweir 832*cdf0e10cSrcweir xColumnsAppend->appendByDescriptor( xColumnDesc ); 833*cdf0e10cSrcweir } 834*cdf0e10cSrcweir 835*cdf0e10cSrcweir xTablesAppend->appendByDescriptor( xTableDesc ); 836*cdf0e10cSrcweir 837*cdf0e10cSrcweir // re-open connection 838*cdf0e10cSrcweir // xConnection = xDrvMan->getConnectionWithInfo( aConnUrl, aProps ); 839*cdf0e10cSrcweir // DBG_ASSERT( xConnection.is(), "can't get Connection" ); 840*cdf0e10cSrcweir // if (!xConnection.is()) return SCERR_EXPORT_CONNECT; 841*cdf0e10cSrcweir 842*cdf0e10cSrcweir // get row set for writing 843*cdf0e10cSrcweir uno::Reference<lang::XMultiServiceFactory> xFactory = comphelper::getProcessServiceFactory(); 844*cdf0e10cSrcweir uno::Reference<sdbc::XRowSet> xRowSet( xFactory->createInstance( 845*cdf0e10cSrcweir rtl::OUString::createFromAscii( SC_SERVICE_ROWSET ) ), 846*cdf0e10cSrcweir uno::UNO_QUERY); 847*cdf0e10cSrcweir ::utl::DisposableComponent aRowSetHelper(xRowSet); 848*cdf0e10cSrcweir uno::Reference<beans::XPropertySet> xRowProp( xRowSet, uno::UNO_QUERY ); 849*cdf0e10cSrcweir DBG_ASSERT( xRowProp.is(), "can't get RowSet" ); 850*cdf0e10cSrcweir if (!xRowProp.is()) return SCERR_EXPORT_CONNECT; 851*cdf0e10cSrcweir 852*cdf0e10cSrcweir aAny <<= xConnection; 853*cdf0e10cSrcweir xRowProp->setPropertyValue( 854*cdf0e10cSrcweir rtl::OUString::createFromAscii(SC_DBPROP_ACTIVECONNECTION), aAny ); 855*cdf0e10cSrcweir 856*cdf0e10cSrcweir aAny <<= (sal_Int32) sdb::CommandType::TABLE; 857*cdf0e10cSrcweir xRowProp->setPropertyValue( 858*cdf0e10cSrcweir rtl::OUString::createFromAscii(SC_DBPROP_COMMANDTYPE), aAny ); 859*cdf0e10cSrcweir 860*cdf0e10cSrcweir aAny <<= rtl::OUString( aTabName ); 861*cdf0e10cSrcweir xRowProp->setPropertyValue( 862*cdf0e10cSrcweir rtl::OUString::createFromAscii(SC_DBPROP_COMMAND), aAny ); 863*cdf0e10cSrcweir 864*cdf0e10cSrcweir xRowSet->execute(); 865*cdf0e10cSrcweir 866*cdf0e10cSrcweir // write data rows 867*cdf0e10cSrcweir 868*cdf0e10cSrcweir uno::Reference<sdbc::XResultSetUpdate> xResultUpdate( xRowSet, uno::UNO_QUERY ); 869*cdf0e10cSrcweir DBG_ASSERT( xResultUpdate.is(), "can't get XResultSetUpdate" ); 870*cdf0e10cSrcweir if (!xResultUpdate.is()) return SCERR_EXPORT_CONNECT; 871*cdf0e10cSrcweir 872*cdf0e10cSrcweir uno::Reference<sdbc::XRowUpdate> xRowUpdate( xRowSet, uno::UNO_QUERY ); 873*cdf0e10cSrcweir DBG_ASSERT( xRowUpdate.is(), "can't get XRowUpdate" ); 874*cdf0e10cSrcweir if (!xRowUpdate.is()) return SCERR_EXPORT_CONNECT; 875*cdf0e10cSrcweir 876*cdf0e10cSrcweir SCROW nFirstDataRow = ( bHasFieldNames ? nFirstRow + 1 : nFirstRow ); 877*cdf0e10cSrcweir double fVal; 878*cdf0e10cSrcweir 879*cdf0e10cSrcweir for ( nDocRow = nFirstDataRow; nDocRow <= nLastRow; nDocRow++ ) 880*cdf0e10cSrcweir { 881*cdf0e10cSrcweir xResultUpdate->moveToInsertRow(); 882*cdf0e10cSrcweir 883*cdf0e10cSrcweir for (nCol=0; nCol<nColCount; nCol++) 884*cdf0e10cSrcweir { 885*cdf0e10cSrcweir SCCOL nDocCol = sal::static_int_cast<SCCOL>( nFirstCol + nCol ); 886*cdf0e10cSrcweir 887*cdf0e10cSrcweir switch (pColTypes[nCol]) 888*cdf0e10cSrcweir { 889*cdf0e10cSrcweir case sdbc::DataType::LONGVARCHAR: 890*cdf0e10cSrcweir { 891*cdf0e10cSrcweir ScBaseCell* pCell; 892*cdf0e10cSrcweir aDocument.GetCell( nDocCol, nDocRow, nTab, pCell ); 893*cdf0e10cSrcweir if ( pCell && pCell->GetCellType() != CELLTYPE_NOTE ) 894*cdf0e10cSrcweir { 895*cdf0e10cSrcweir if ( pCell->GetCellType() == CELLTYPE_EDIT ) 896*cdf0e10cSrcweir { // #60761# Paragraphs erhalten 897*cdf0e10cSrcweir lcl_getLongVarCharEditString( aString, 898*cdf0e10cSrcweir pCell, aEditEngine); 899*cdf0e10cSrcweir } 900*cdf0e10cSrcweir else 901*cdf0e10cSrcweir { 902*cdf0e10cSrcweir lcl_getLongVarCharString( aString, pCell, 903*cdf0e10cSrcweir aDocument, nDocCol, nDocRow, nTab, 904*cdf0e10cSrcweir *pNumFmt); 905*cdf0e10cSrcweir } 906*cdf0e10cSrcweir xRowUpdate->updateString( nCol+1, aString ); 907*cdf0e10cSrcweir } 908*cdf0e10cSrcweir else 909*cdf0e10cSrcweir xRowUpdate->updateNull( nCol+1 ); 910*cdf0e10cSrcweir } 911*cdf0e10cSrcweir break; 912*cdf0e10cSrcweir 913*cdf0e10cSrcweir case sdbc::DataType::VARCHAR: 914*cdf0e10cSrcweir aDocument.GetString( nDocCol, nDocRow, nTab, aString ); 915*cdf0e10cSrcweir xRowUpdate->updateString( nCol+1, aString ); 916*cdf0e10cSrcweir if ( nErr == eERR_OK && pColLengths[nCol] < aString.Len() ) 917*cdf0e10cSrcweir nErr = SCWARN_EXPORT_DATALOST; 918*cdf0e10cSrcweir break; 919*cdf0e10cSrcweir 920*cdf0e10cSrcweir case sdbc::DataType::DATE: 921*cdf0e10cSrcweir { 922*cdf0e10cSrcweir aDocument.GetValue( nDocCol, nDocRow, nTab, fVal ); 923*cdf0e10cSrcweir // #39274# zwischen 0 Wert und 0 kein Wert unterscheiden 924*cdf0e10cSrcweir sal_Bool bIsNull = (fVal == 0.0); 925*cdf0e10cSrcweir if ( bIsNull ) 926*cdf0e10cSrcweir bIsNull = !aDocument.HasValueData( nDocCol, nDocRow, nTab ); 927*cdf0e10cSrcweir if ( bIsNull ) 928*cdf0e10cSrcweir { 929*cdf0e10cSrcweir xRowUpdate->updateNull( nCol+1 ); 930*cdf0e10cSrcweir if ( nErr == eERR_OK && 931*cdf0e10cSrcweir aDocument.HasStringData( nDocCol, nDocRow, nTab ) ) 932*cdf0e10cSrcweir nErr = SCWARN_EXPORT_DATALOST; 933*cdf0e10cSrcweir } 934*cdf0e10cSrcweir else 935*cdf0e10cSrcweir { 936*cdf0e10cSrcweir Date aDate = *(pNumFmt->GetNullDate()); // tools date 937*cdf0e10cSrcweir aDate += (long)fVal; //! approxfloor? 938*cdf0e10cSrcweir util::Date aUnoDate( aDate.GetDay(), aDate.GetMonth(), aDate.GetYear() ); 939*cdf0e10cSrcweir xRowUpdate->updateDate( nCol+1, aUnoDate ); 940*cdf0e10cSrcweir } 941*cdf0e10cSrcweir } 942*cdf0e10cSrcweir break; 943*cdf0e10cSrcweir 944*cdf0e10cSrcweir case sdbc::DataType::DECIMAL: 945*cdf0e10cSrcweir case sdbc::DataType::BIT: 946*cdf0e10cSrcweir aDocument.GetValue( nDocCol, nDocRow, nTab, fVal ); 947*cdf0e10cSrcweir if ( fVal == 0.0 && nErr == eERR_OK && 948*cdf0e10cSrcweir aDocument.HasStringData( nDocCol, nDocRow, nTab ) ) 949*cdf0e10cSrcweir nErr = SCWARN_EXPORT_DATALOST; 950*cdf0e10cSrcweir if ( pColTypes[nCol] == sdbc::DataType::BIT ) 951*cdf0e10cSrcweir xRowUpdate->updateBoolean( nCol+1, ( fVal != 0.0 ) ); 952*cdf0e10cSrcweir else 953*cdf0e10cSrcweir xRowUpdate->updateDouble( nCol+1, fVal ); 954*cdf0e10cSrcweir break; 955*cdf0e10cSrcweir 956*cdf0e10cSrcweir default: 957*cdf0e10cSrcweir DBG_ERROR( "ScDocShell::DBaseExport: unknown FieldType" ); 958*cdf0e10cSrcweir if ( nErr == eERR_OK ) 959*cdf0e10cSrcweir nErr = SCWARN_EXPORT_DATALOST; 960*cdf0e10cSrcweir aDocument.GetValue( nDocCol, nDocRow, nTab, fVal ); 961*cdf0e10cSrcweir xRowUpdate->updateDouble( nCol+1, fVal ); 962*cdf0e10cSrcweir } 963*cdf0e10cSrcweir } 964*cdf0e10cSrcweir 965*cdf0e10cSrcweir xResultUpdate->insertRow(); 966*cdf0e10cSrcweir 967*cdf0e10cSrcweir //! error handling and recovery of old 968*cdf0e10cSrcweir //! ScDocShell::SbaSdbExport is still missing! 969*cdf0e10cSrcweir 970*cdf0e10cSrcweir if ( !aProgress.SetStateOnPercent( nDocRow - nFirstRow ) ) 971*cdf0e10cSrcweir { // UserBreak 972*cdf0e10cSrcweir nErr = SCERR_EXPORT_DATA; 973*cdf0e10cSrcweir break; 974*cdf0e10cSrcweir } 975*cdf0e10cSrcweir } 976*cdf0e10cSrcweir 977*cdf0e10cSrcweir comphelper::disposeComponent( xRowSet ); 978*cdf0e10cSrcweir comphelper::disposeComponent( xConnection ); 979*cdf0e10cSrcweir } 980*cdf0e10cSrcweir catch ( sdbc::SQLException& aException ) 981*cdf0e10cSrcweir { 982*cdf0e10cSrcweir sal_Int32 nError = aException.ErrorCode; 983*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 984*cdf0e10cSrcweir fprintf( stderr, "ScDocShell::DBaseExport: SQLException ErrorCode: %d, SQLState: %s, Message: %s\n", 985*cdf0e10cSrcweir (int)nError, OUStringToOString( aException.SQLState, 986*cdf0e10cSrcweir RTL_TEXTENCODING_UTF8).getStr(), OUStringToOString( 987*cdf0e10cSrcweir aException.Message, RTL_TEXTENCODING_UTF8).getStr()); 988*cdf0e10cSrcweir #endif 989*cdf0e10cSrcweir if (nError == 22018 || nError == 22001) 990*cdf0e10cSrcweir { 991*cdf0e10cSrcweir // SQL error 22018: Character not in target encoding. 992*cdf0e10cSrcweir // SQL error 22001: String length exceeds field width (after encoding). 993*cdf0e10cSrcweir bool bEncErr = (nError == 22018); 994*cdf0e10cSrcweir bool bIsOctetTextEncoding = rtl_isOctetTextEncoding( eCharSet); 995*cdf0e10cSrcweir DBG_ASSERT( !bEncErr || bIsOctetTextEncoding, "ScDocShell::DBaseExport: encoding error and not an octect textencoding"); 996*cdf0e10cSrcweir SCCOL nDocCol = nFirstCol; 997*cdf0e10cSrcweir const sal_Int32* pColTypes = aColTypes.getConstArray(); 998*cdf0e10cSrcweir const sal_Int32* pColLengths = aColLengths.getConstArray(); 999*cdf0e10cSrcweir ScHorizontalCellIterator aIter( &aDocument, nTab, nFirstCol, 1000*cdf0e10cSrcweir nDocRow, nLastCol, nDocRow); 1001*cdf0e10cSrcweir ScBaseCell* pCell = NULL; 1002*cdf0e10cSrcweir bool bTest = true; 1003*cdf0e10cSrcweir while (bTest && ((pCell = aIter.GetNext( nDocCol, nDocRow)) != NULL)) 1004*cdf0e10cSrcweir { 1005*cdf0e10cSrcweir SCCOL nCol = nDocCol - nFirstCol; 1006*cdf0e10cSrcweir switch (pColTypes[nCol]) 1007*cdf0e10cSrcweir { 1008*cdf0e10cSrcweir case sdbc::DataType::LONGVARCHAR: 1009*cdf0e10cSrcweir { 1010*cdf0e10cSrcweir if ( pCell->GetCellType() != CELLTYPE_NOTE ) 1011*cdf0e10cSrcweir { 1012*cdf0e10cSrcweir if ( pCell->GetCellType() == CELLTYPE_EDIT ) 1013*cdf0e10cSrcweir lcl_getLongVarCharEditString( aString, 1014*cdf0e10cSrcweir pCell, aEditEngine); 1015*cdf0e10cSrcweir else 1016*cdf0e10cSrcweir lcl_getLongVarCharString( aString, 1017*cdf0e10cSrcweir pCell, aDocument, nDocCol, 1018*cdf0e10cSrcweir nDocRow, nTab, *pNumFmt); 1019*cdf0e10cSrcweir } 1020*cdf0e10cSrcweir } 1021*cdf0e10cSrcweir break; 1022*cdf0e10cSrcweir 1023*cdf0e10cSrcweir case sdbc::DataType::VARCHAR: 1024*cdf0e10cSrcweir aDocument.GetString( nDocCol, nDocRow, nTab, aString); 1025*cdf0e10cSrcweir break; 1026*cdf0e10cSrcweir 1027*cdf0e10cSrcweir // NOTE: length of DECIMAL fields doesn't need to be 1028*cdf0e10cSrcweir // checked here, the database driver adjusts the field 1029*cdf0e10cSrcweir // width accordingly. 1030*cdf0e10cSrcweir 1031*cdf0e10cSrcweir default: 1032*cdf0e10cSrcweir bTest = false; 1033*cdf0e10cSrcweir } 1034*cdf0e10cSrcweir if (bTest) 1035*cdf0e10cSrcweir { 1036*cdf0e10cSrcweir sal_Int32 nLen; 1037*cdf0e10cSrcweir if (bIsOctetTextEncoding) 1038*cdf0e10cSrcweir { 1039*cdf0e10cSrcweir rtl::OUString aOUString( aString); 1040*cdf0e10cSrcweir rtl::OString aOString; 1041*cdf0e10cSrcweir if (!aOUString.convertToString( &aOString, eCharSet, 1042*cdf0e10cSrcweir RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR | 1043*cdf0e10cSrcweir RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)) 1044*cdf0e10cSrcweir { 1045*cdf0e10cSrcweir bTest = false; 1046*cdf0e10cSrcweir bEncErr = true; 1047*cdf0e10cSrcweir } 1048*cdf0e10cSrcweir nLen = aOString.getLength(); 1049*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 1050*cdf0e10cSrcweir if (!bTest) 1051*cdf0e10cSrcweir fprintf( stderr, "ScDocShell::DBaseExport encoding error, string with default replacements: ``%s''\n", 1052*cdf0e10cSrcweir OUStringToOString( aOUString, eCharSet).getStr()); 1053*cdf0e10cSrcweir #endif 1054*cdf0e10cSrcweir } 1055*cdf0e10cSrcweir else 1056*cdf0e10cSrcweir nLen = aString.Len() * sizeof(sal_Unicode); 1057*cdf0e10cSrcweir if (!bEncErr && 1058*cdf0e10cSrcweir pColTypes[nCol] != sdbc::DataType::LONGVARCHAR && 1059*cdf0e10cSrcweir pColLengths[nCol] < nLen) 1060*cdf0e10cSrcweir { 1061*cdf0e10cSrcweir bTest = false; 1062*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 1063*cdf0e10cSrcweir fprintf( stderr, "ScDocShell::DBaseExport: field width: %d, encoded length: %d\n", 1064*cdf0e10cSrcweir (int)pColLengths[nCol], (int)nLen); 1065*cdf0e10cSrcweir #endif 1066*cdf0e10cSrcweir } 1067*cdf0e10cSrcweir } 1068*cdf0e10cSrcweir else 1069*cdf0e10cSrcweir bTest = true; 1070*cdf0e10cSrcweir } 1071*cdf0e10cSrcweir String sPosition( ScAddress( nDocCol, nDocRow, nTab).GetColRowString()); 1072*cdf0e10cSrcweir String sEncoding( SvxTextEncodingTable().GetTextString( eCharSet)); 1073*cdf0e10cSrcweir nErr = *new TwoStringErrorInfo( (bEncErr ? SCERR_EXPORT_ENCODING : 1074*cdf0e10cSrcweir SCERR_EXPORT_FIELDWIDTH), sPosition, sEncoding, 1075*cdf0e10cSrcweir ERRCODE_BUTTON_OK | ERRCODE_MSG_ERROR); 1076*cdf0e10cSrcweir } 1077*cdf0e10cSrcweir else if ( aException.Message.getLength() ) 1078*cdf0e10cSrcweir nErr = *new StringErrorInfo( (SCERR_EXPORT_SQLEXCEPTION), aException.Message, ERRCODE_BUTTON_OK | ERRCODE_MSG_ERROR); 1079*cdf0e10cSrcweir else 1080*cdf0e10cSrcweir nErr = SCERR_EXPORT_DATA; 1081*cdf0e10cSrcweir } 1082*cdf0e10cSrcweir catch ( uno::Exception& ) 1083*cdf0e10cSrcweir { 1084*cdf0e10cSrcweir DBG_ERROR("Unexpected exception in database"); 1085*cdf0e10cSrcweir nErr = ERRCODE_IO_GENERAL; 1086*cdf0e10cSrcweir } 1087*cdf0e10cSrcweir 1088*cdf0e10cSrcweir return nErr; 1089*cdf0e10cSrcweir } 1090*cdf0e10cSrcweir 1091*cdf0e10cSrcweir 1092