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 <comphelper/processfactory.hxx> 36*cdf0e10cSrcweir #include <comphelper/types.hxx> 37*cdf0e10cSrcweir #include <vcl/msgbox.hxx> 38*cdf0e10cSrcweir #include <tools/debug.hxx> 39*cdf0e10cSrcweir #include <svx/dataaccessdescriptor.hxx> 40*cdf0e10cSrcweir #include <sfx2/viewfrm.hxx> 41*cdf0e10cSrcweir 42*cdf0e10cSrcweir #include <com/sun/star/sdb/CommandType.hpp> 43*cdf0e10cSrcweir #include <com/sun/star/sdb/XCompletedExecution.hpp> 44*cdf0e10cSrcweir #include <com/sun/star/sdbc/XRow.hpp> 45*cdf0e10cSrcweir #include <com/sun/star/sdbc/XRowSet.hpp> 46*cdf0e10cSrcweir #include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp> 47*cdf0e10cSrcweir #include <com/sun/star/sdbcx/XRowLocate.hpp> 48*cdf0e10cSrcweir #include <com/sun/star/lang/XMultiServiceFactory.hpp> 49*cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp> 50*cdf0e10cSrcweir #include <com/sun/star/frame/XDispatchProvider.hpp> 51*cdf0e10cSrcweir #include <com/sun/star/frame/FrameSearchFlag.hpp> 52*cdf0e10cSrcweir #include <com/sun/star/view/XSelectionSupplier.hpp> 53*cdf0e10cSrcweir 54*cdf0e10cSrcweir 55*cdf0e10cSrcweir #include "dbdocfun.hxx" 56*cdf0e10cSrcweir #include "docsh.hxx" 57*cdf0e10cSrcweir #include "globstr.hrc" 58*cdf0e10cSrcweir #include "scerrors.hxx" 59*cdf0e10cSrcweir #include "dbcolect.hxx" 60*cdf0e10cSrcweir #include "markdata.hxx" 61*cdf0e10cSrcweir #include "undodat.hxx" 62*cdf0e10cSrcweir #include "progress.hxx" 63*cdf0e10cSrcweir #include "patattr.hxx" 64*cdf0e10cSrcweir #include "docpool.hxx" 65*cdf0e10cSrcweir #include "attrib.hxx" 66*cdf0e10cSrcweir #include "dbdocutl.hxx" 67*cdf0e10cSrcweir #include "editable.hxx" 68*cdf0e10cSrcweir #include "hints.hxx" 69*cdf0e10cSrcweir #include "miscuno.hxx" 70*cdf0e10cSrcweir 71*cdf0e10cSrcweir using namespace com::sun::star; 72*cdf0e10cSrcweir 73*cdf0e10cSrcweir #define SC_SERVICE_ROWSET "com.sun.star.sdb.RowSet" 74*cdf0e10cSrcweir #define SC_SERVICE_INTHANDLER "com.sun.star.task.InteractionHandler" 75*cdf0e10cSrcweir 76*cdf0e10cSrcweir //! move to a header file? 77*cdf0e10cSrcweir #define SC_DBPROP_DATASOURCENAME "DataSourceName" 78*cdf0e10cSrcweir #define SC_DBPROP_COMMAND "Command" 79*cdf0e10cSrcweir #define SC_DBPROP_COMMANDTYPE "CommandType" 80*cdf0e10cSrcweir #define SC_DBPROP_SELECTION "Selection" 81*cdf0e10cSrcweir #define SC_DBPROP_CURSOR "Cursor" 82*cdf0e10cSrcweir 83*cdf0e10cSrcweir // static 84*cdf0e10cSrcweir void ScDBDocFunc::ShowInBeamer( const ScImportParam& rParam, SfxViewFrame* pFrame ) 85*cdf0e10cSrcweir { 86*cdf0e10cSrcweir // called after opening the database beamer 87*cdf0e10cSrcweir 88*cdf0e10cSrcweir if ( !pFrame || !rParam.bImport ) 89*cdf0e10cSrcweir return; 90*cdf0e10cSrcweir 91*cdf0e10cSrcweir uno::Reference<frame::XFrame> xFrame = pFrame->GetFrame().GetFrameInterface(); 92*cdf0e10cSrcweir uno::Reference<frame::XDispatchProvider> xDP(xFrame, uno::UNO_QUERY); 93*cdf0e10cSrcweir 94*cdf0e10cSrcweir uno::Reference<frame::XFrame> xBeamerFrame = xFrame->findFrame( 95*cdf0e10cSrcweir rtl::OUString::createFromAscii("_beamer"), 96*cdf0e10cSrcweir frame::FrameSearchFlag::CHILDREN); 97*cdf0e10cSrcweir if (xBeamerFrame.is()) 98*cdf0e10cSrcweir { 99*cdf0e10cSrcweir uno::Reference<frame::XController> xController = xBeamerFrame->getController(); 100*cdf0e10cSrcweir uno::Reference<view::XSelectionSupplier> xControllerSelection(xController, uno::UNO_QUERY); 101*cdf0e10cSrcweir if (xControllerSelection.is()) 102*cdf0e10cSrcweir { 103*cdf0e10cSrcweir sal_Int32 nType = rParam.bSql ? sdb::CommandType::COMMAND : 104*cdf0e10cSrcweir ( (rParam.nType == ScDbQuery) ? sdb::CommandType::QUERY : 105*cdf0e10cSrcweir sdb::CommandType::TABLE ); 106*cdf0e10cSrcweir 107*cdf0e10cSrcweir ::svx::ODataAccessDescriptor aSelection; 108*cdf0e10cSrcweir aSelection.setDataSource(rtl::OUString( rParam.aDBName )); 109*cdf0e10cSrcweir aSelection[svx::daCommand] <<= rtl::OUString( rParam.aStatement ); 110*cdf0e10cSrcweir aSelection[svx::daCommandType] <<= nType; 111*cdf0e10cSrcweir 112*cdf0e10cSrcweir xControllerSelection->select(uno::makeAny(aSelection.createPropertyValueSequence())); 113*cdf0e10cSrcweir } 114*cdf0e10cSrcweir else 115*cdf0e10cSrcweir { 116*cdf0e10cSrcweir DBG_ERROR("no selection supplier in the beamer!"); 117*cdf0e10cSrcweir } 118*cdf0e10cSrcweir } 119*cdf0e10cSrcweir } 120*cdf0e10cSrcweir 121*cdf0e10cSrcweir // ----------------------------------------------------------------- 122*cdf0e10cSrcweir 123*cdf0e10cSrcweir sal_Bool ScDBDocFunc::DoImportUno( const ScAddress& rPos, 124*cdf0e10cSrcweir const uno::Sequence<beans::PropertyValue>& aArgs ) 125*cdf0e10cSrcweir { 126*cdf0e10cSrcweir svx::ODataAccessDescriptor aDesc( aArgs ); // includes selection and result set 127*cdf0e10cSrcweir 128*cdf0e10cSrcweir // create database range 129*cdf0e10cSrcweir ScDBData* pDBData = rDocShell.GetDBData( ScRange(rPos), SC_DB_IMPORT, SC_DBSEL_KEEP ); 130*cdf0e10cSrcweir DBG_ASSERT(pDBData, "can't create DB data"); 131*cdf0e10cSrcweir String sTarget = pDBData->GetName(); 132*cdf0e10cSrcweir 133*cdf0e10cSrcweir UpdateImport( sTarget, aDesc ); 134*cdf0e10cSrcweir 135*cdf0e10cSrcweir return sal_True; 136*cdf0e10cSrcweir } 137*cdf0e10cSrcweir 138*cdf0e10cSrcweir // ----------------------------------------------------------------- 139*cdf0e10cSrcweir 140*cdf0e10cSrcweir sal_Bool ScDBDocFunc::DoImport( SCTAB nTab, const ScImportParam& rParam, 141*cdf0e10cSrcweir const svx::ODataAccessDescriptor* pDescriptor, sal_Bool bRecord, sal_Bool bAddrInsert ) 142*cdf0e10cSrcweir { 143*cdf0e10cSrcweir ScDocument* pDoc = rDocShell.GetDocument(); 144*cdf0e10cSrcweir 145*cdf0e10cSrcweir if (bRecord && !pDoc->IsUndoEnabled()) 146*cdf0e10cSrcweir bRecord = sal_False; 147*cdf0e10cSrcweir 148*cdf0e10cSrcweir ScDBData* pDBData = 0; 149*cdf0e10cSrcweir if ( !bAddrInsert ) 150*cdf0e10cSrcweir { 151*cdf0e10cSrcweir pDBData = pDoc->GetDBAtArea( nTab, rParam.nCol1, rParam.nRow1, 152*cdf0e10cSrcweir rParam.nCol2, rParam.nRow2 ); 153*cdf0e10cSrcweir if (!pDBData) 154*cdf0e10cSrcweir { 155*cdf0e10cSrcweir DBG_ERROR( "DoImport: no DBData" ); 156*cdf0e10cSrcweir return sal_False; 157*cdf0e10cSrcweir } 158*cdf0e10cSrcweir } 159*cdf0e10cSrcweir 160*cdf0e10cSrcweir Window* pWaitWin = rDocShell.GetActiveDialogParent(); 161*cdf0e10cSrcweir if (pWaitWin) 162*cdf0e10cSrcweir pWaitWin->EnterWait(); 163*cdf0e10cSrcweir ScDocShellModificator aModificator( rDocShell ); 164*cdf0e10cSrcweir 165*cdf0e10cSrcweir sal_Bool bSuccess = sal_False; 166*cdf0e10cSrcweir sal_Bool bApi = sal_False; //! pass as argument 167*cdf0e10cSrcweir sal_Bool bTruncated = sal_False; // for warning 168*cdf0e10cSrcweir sal_uInt16 nErrStringId = 0; 169*cdf0e10cSrcweir String aErrorMessage; 170*cdf0e10cSrcweir 171*cdf0e10cSrcweir SCCOL nCol = rParam.nCol1; 172*cdf0e10cSrcweir SCROW nRow = rParam.nRow1; 173*cdf0e10cSrcweir SCCOL nEndCol = nCol; // end of resulting database area 174*cdf0e10cSrcweir SCROW nEndRow = nRow; 175*cdf0e10cSrcweir long i; 176*cdf0e10cSrcweir 177*cdf0e10cSrcweir sal_Bool bDoSelection = sal_False; 178*cdf0e10cSrcweir sal_Bool bRealSelection = sal_False; // sal_True if not everything is selected 179*cdf0e10cSrcweir sal_Bool bBookmarkSelection = sal_False; 180*cdf0e10cSrcweir sal_Int32 nListPos = 0; 181*cdf0e10cSrcweir sal_Int32 nRowsRead = 0; 182*cdf0e10cSrcweir sal_Int32 nListCount = 0; 183*cdf0e10cSrcweir 184*cdf0e10cSrcweir uno::Sequence<uno::Any> aSelection; 185*cdf0e10cSrcweir if ( pDescriptor && pDescriptor->has(svx::daSelection) ) 186*cdf0e10cSrcweir { 187*cdf0e10cSrcweir (*pDescriptor)[svx::daSelection] >>= aSelection; 188*cdf0e10cSrcweir nListCount = aSelection.getLength(); 189*cdf0e10cSrcweir if ( nListCount > 0 ) 190*cdf0e10cSrcweir { 191*cdf0e10cSrcweir bDoSelection = sal_True; 192*cdf0e10cSrcweir if ( pDescriptor->has(svx::daBookmarkSelection) ) 193*cdf0e10cSrcweir bBookmarkSelection = ScUnoHelpFunctions::GetBoolFromAny( (*pDescriptor)[svx::daBookmarkSelection] ); 194*cdf0e10cSrcweir if ( bBookmarkSelection ) 195*cdf0e10cSrcweir { 196*cdf0e10cSrcweir // From bookmarks, there's no way to detect if all records are selected. 197*cdf0e10cSrcweir // Rely on base to pass no selection in that case. 198*cdf0e10cSrcweir bRealSelection = sal_True; 199*cdf0e10cSrcweir } 200*cdf0e10cSrcweir } 201*cdf0e10cSrcweir } 202*cdf0e10cSrcweir 203*cdf0e10cSrcweir uno::Reference<sdbc::XResultSet> xResultSet; 204*cdf0e10cSrcweir if ( pDescriptor && pDescriptor->has(svx::daCursor) ) 205*cdf0e10cSrcweir xResultSet.set((*pDescriptor)[svx::daCursor], uno::UNO_QUERY); 206*cdf0e10cSrcweir 207*cdf0e10cSrcweir // ImportDoc - also used for Redo 208*cdf0e10cSrcweir ScDocument* pImportDoc = new ScDocument( SCDOCMODE_UNDO ); 209*cdf0e10cSrcweir pImportDoc->InitUndo( pDoc, nTab, nTab ); 210*cdf0e10cSrcweir ScColumn::bDoubleAlloc = sal_True; 211*cdf0e10cSrcweir 212*cdf0e10cSrcweir // 213*cdf0e10cSrcweir // get data from database into import document 214*cdf0e10cSrcweir // 215*cdf0e10cSrcweir 216*cdf0e10cSrcweir try 217*cdf0e10cSrcweir { 218*cdf0e10cSrcweir // progress bar 219*cdf0e10cSrcweir // only text (title is still needed, for the cancel button) 220*cdf0e10cSrcweir ScProgress aProgress( &rDocShell, ScGlobal::GetRscString(STR_UNDO_IMPORTDATA), 0 ); 221*cdf0e10cSrcweir sal_uInt16 nInserted = 0; 222*cdf0e10cSrcweir 223*cdf0e10cSrcweir uno::Reference<sdbc::XRowSet> xRowSet = uno::Reference<sdbc::XRowSet>( 224*cdf0e10cSrcweir xResultSet, uno::UNO_QUERY ); 225*cdf0e10cSrcweir sal_Bool bDispose = sal_False; 226*cdf0e10cSrcweir if ( !xRowSet.is() ) 227*cdf0e10cSrcweir { 228*cdf0e10cSrcweir bDispose = sal_True; 229*cdf0e10cSrcweir xRowSet = uno::Reference<sdbc::XRowSet>( 230*cdf0e10cSrcweir comphelper::getProcessServiceFactory()->createInstance( 231*cdf0e10cSrcweir rtl::OUString::createFromAscii( SC_SERVICE_ROWSET ) ), 232*cdf0e10cSrcweir uno::UNO_QUERY); 233*cdf0e10cSrcweir uno::Reference<beans::XPropertySet> xRowProp( xRowSet, uno::UNO_QUERY ); 234*cdf0e10cSrcweir DBG_ASSERT( xRowProp.is(), "can't get RowSet" ); 235*cdf0e10cSrcweir if ( xRowProp.is() ) 236*cdf0e10cSrcweir { 237*cdf0e10cSrcweir // 238*cdf0e10cSrcweir // set source parameters 239*cdf0e10cSrcweir // 240*cdf0e10cSrcweir 241*cdf0e10cSrcweir sal_Int32 nType = rParam.bSql ? sdb::CommandType::COMMAND : 242*cdf0e10cSrcweir ( (rParam.nType == ScDbQuery) ? sdb::CommandType::QUERY : 243*cdf0e10cSrcweir sdb::CommandType::TABLE ); 244*cdf0e10cSrcweir uno::Any aAny; 245*cdf0e10cSrcweir 246*cdf0e10cSrcweir aAny <<= rtl::OUString( rParam.aDBName ); 247*cdf0e10cSrcweir xRowProp->setPropertyValue( 248*cdf0e10cSrcweir rtl::OUString::createFromAscii(SC_DBPROP_DATASOURCENAME), aAny ); 249*cdf0e10cSrcweir 250*cdf0e10cSrcweir aAny <<= rtl::OUString( rParam.aStatement ); 251*cdf0e10cSrcweir xRowProp->setPropertyValue( 252*cdf0e10cSrcweir rtl::OUString::createFromAscii(SC_DBPROP_COMMAND), aAny ); 253*cdf0e10cSrcweir 254*cdf0e10cSrcweir aAny <<= nType; 255*cdf0e10cSrcweir xRowProp->setPropertyValue( 256*cdf0e10cSrcweir rtl::OUString::createFromAscii(SC_DBPROP_COMMANDTYPE), aAny ); 257*cdf0e10cSrcweir 258*cdf0e10cSrcweir uno::Reference<sdb::XCompletedExecution> xExecute( xRowSet, uno::UNO_QUERY ); 259*cdf0e10cSrcweir if ( xExecute.is() ) 260*cdf0e10cSrcweir { 261*cdf0e10cSrcweir uno::Reference<task::XInteractionHandler> xHandler( 262*cdf0e10cSrcweir comphelper::getProcessServiceFactory()->createInstance( 263*cdf0e10cSrcweir rtl::OUString::createFromAscii( SC_SERVICE_INTHANDLER ) ), 264*cdf0e10cSrcweir uno::UNO_QUERY); 265*cdf0e10cSrcweir xExecute->executeWithCompletion( xHandler ); 266*cdf0e10cSrcweir } 267*cdf0e10cSrcweir else 268*cdf0e10cSrcweir xRowSet->execute(); 269*cdf0e10cSrcweir } 270*cdf0e10cSrcweir } 271*cdf0e10cSrcweir if ( xRowSet.is() ) 272*cdf0e10cSrcweir { 273*cdf0e10cSrcweir // 274*cdf0e10cSrcweir // get column descriptions 275*cdf0e10cSrcweir // 276*cdf0e10cSrcweir 277*cdf0e10cSrcweir long nColCount = 0; 278*cdf0e10cSrcweir uno::Reference<sdbc::XResultSetMetaData> xMeta; 279*cdf0e10cSrcweir uno::Reference<sdbc::XResultSetMetaDataSupplier> xMetaSupp( xRowSet, uno::UNO_QUERY ); 280*cdf0e10cSrcweir if ( xMetaSupp.is() ) 281*cdf0e10cSrcweir xMeta = xMetaSupp->getMetaData(); 282*cdf0e10cSrcweir if ( xMeta.is() ) 283*cdf0e10cSrcweir nColCount = xMeta->getColumnCount(); // this is the number of real columns 284*cdf0e10cSrcweir 285*cdf0e10cSrcweir if ( rParam.nCol1 + nColCount - 1 > MAXCOL ) 286*cdf0e10cSrcweir { 287*cdf0e10cSrcweir nColCount = 0; 288*cdf0e10cSrcweir //! error message 289*cdf0e10cSrcweir } 290*cdf0e10cSrcweir 291*cdf0e10cSrcweir uno::Reference<sdbcx::XRowLocate> xLocate; 292*cdf0e10cSrcweir if ( bBookmarkSelection ) 293*cdf0e10cSrcweir { 294*cdf0e10cSrcweir xLocate.set( xRowSet, uno::UNO_QUERY ); 295*cdf0e10cSrcweir if ( !xLocate.is() ) 296*cdf0e10cSrcweir { 297*cdf0e10cSrcweir DBG_ERRORFILE("can't get XRowLocate"); 298*cdf0e10cSrcweir bDoSelection = bRealSelection = bBookmarkSelection = sal_False; 299*cdf0e10cSrcweir } 300*cdf0e10cSrcweir } 301*cdf0e10cSrcweir 302*cdf0e10cSrcweir uno::Reference<sdbc::XRow> xRow( xRowSet, uno::UNO_QUERY ); 303*cdf0e10cSrcweir if ( nColCount > 0 && xRow.is() ) 304*cdf0e10cSrcweir { 305*cdf0e10cSrcweir nEndCol = (SCCOL)( rParam.nCol1 + nColCount - 1 ); 306*cdf0e10cSrcweir 307*cdf0e10cSrcweir uno::Sequence<sal_Int32> aColTypes( nColCount ); // column types 308*cdf0e10cSrcweir uno::Sequence<sal_Bool> aColCurr( nColCount ); // currency flag is not in types 309*cdf0e10cSrcweir sal_Int32* pTypeArr = aColTypes.getArray(); 310*cdf0e10cSrcweir sal_Bool* pCurrArr = aColCurr.getArray(); 311*cdf0e10cSrcweir for (i=0; i<nColCount; i++) 312*cdf0e10cSrcweir { 313*cdf0e10cSrcweir pTypeArr[i] = xMeta->getColumnType( i+1 ); 314*cdf0e10cSrcweir pCurrArr[i] = xMeta->isCurrency( i+1 ); 315*cdf0e10cSrcweir } 316*cdf0e10cSrcweir 317*cdf0e10cSrcweir if ( !bAddrInsert ) // read column names 318*cdf0e10cSrcweir { 319*cdf0e10cSrcweir nCol = rParam.nCol1; 320*cdf0e10cSrcweir for (i=0; i<nColCount; i++) 321*cdf0e10cSrcweir { 322*cdf0e10cSrcweir pImportDoc->SetString( nCol, nRow, nTab, 323*cdf0e10cSrcweir xMeta->getColumnLabel( i+1 ) ); 324*cdf0e10cSrcweir ++nCol; 325*cdf0e10cSrcweir } 326*cdf0e10cSrcweir ++nRow; 327*cdf0e10cSrcweir } 328*cdf0e10cSrcweir 329*cdf0e10cSrcweir sal_Bool bEnd = sal_False; 330*cdf0e10cSrcweir if ( !bDoSelection ) 331*cdf0e10cSrcweir xRowSet->beforeFirst(); 332*cdf0e10cSrcweir while ( !bEnd ) 333*cdf0e10cSrcweir { 334*cdf0e10cSrcweir // skip rows that are not selected 335*cdf0e10cSrcweir if ( !bDoSelection ) 336*cdf0e10cSrcweir { 337*cdf0e10cSrcweir if ( (bEnd = !xRowSet->next()) == sal_False ) 338*cdf0e10cSrcweir ++nRowsRead; 339*cdf0e10cSrcweir } 340*cdf0e10cSrcweir else 341*cdf0e10cSrcweir { 342*cdf0e10cSrcweir if (nListPos < nListCount) 343*cdf0e10cSrcweir { 344*cdf0e10cSrcweir if ( bBookmarkSelection ) 345*cdf0e10cSrcweir { 346*cdf0e10cSrcweir bEnd = !xLocate->moveToBookmark(aSelection[nListPos]); 347*cdf0e10cSrcweir } 348*cdf0e10cSrcweir else // use record numbers 349*cdf0e10cSrcweir { 350*cdf0e10cSrcweir sal_Int32 nNextRow = 0; 351*cdf0e10cSrcweir aSelection[nListPos] >>= nNextRow; 352*cdf0e10cSrcweir if ( nRowsRead+1 < nNextRow ) 353*cdf0e10cSrcweir bRealSelection = sal_True; 354*cdf0e10cSrcweir bEnd = !xRowSet->absolute(nRowsRead = nNextRow); 355*cdf0e10cSrcweir } 356*cdf0e10cSrcweir ++nListPos; 357*cdf0e10cSrcweir } 358*cdf0e10cSrcweir else 359*cdf0e10cSrcweir { 360*cdf0e10cSrcweir if ( !bBookmarkSelection && xRowSet->next() ) 361*cdf0e10cSrcweir bRealSelection = sal_True; // more data available but not used 362*cdf0e10cSrcweir bEnd = sal_True; 363*cdf0e10cSrcweir } 364*cdf0e10cSrcweir } 365*cdf0e10cSrcweir 366*cdf0e10cSrcweir if ( !bEnd ) 367*cdf0e10cSrcweir { 368*cdf0e10cSrcweir if ( ValidRow(nRow) ) 369*cdf0e10cSrcweir { 370*cdf0e10cSrcweir nCol = rParam.nCol1; 371*cdf0e10cSrcweir for (i=0; i<nColCount; i++) 372*cdf0e10cSrcweir { 373*cdf0e10cSrcweir ScDatabaseDocUtil::PutData( pImportDoc, nCol, nRow, nTab, 374*cdf0e10cSrcweir xRow, i+1, pTypeArr[i], pCurrArr[i] ); 375*cdf0e10cSrcweir ++nCol; 376*cdf0e10cSrcweir } 377*cdf0e10cSrcweir nEndRow = nRow; 378*cdf0e10cSrcweir ++nRow; 379*cdf0e10cSrcweir 380*cdf0e10cSrcweir // progress bar 381*cdf0e10cSrcweir 382*cdf0e10cSrcweir ++nInserted; 383*cdf0e10cSrcweir if (!(nInserted & 15)) 384*cdf0e10cSrcweir { 385*cdf0e10cSrcweir String aPict = ScGlobal::GetRscString( STR_PROGRESS_IMPORT ); 386*cdf0e10cSrcweir String aText = aPict.GetToken(0,'#'); 387*cdf0e10cSrcweir aText += String::CreateFromInt32( nInserted ); 388*cdf0e10cSrcweir aText += aPict.GetToken(1,'#'); 389*cdf0e10cSrcweir 390*cdf0e10cSrcweir if (!aProgress.SetStateText( 0, aText )) // stopped by user? 391*cdf0e10cSrcweir { 392*cdf0e10cSrcweir bEnd = sal_True; 393*cdf0e10cSrcweir bSuccess = sal_False; 394*cdf0e10cSrcweir nErrStringId = STR_DATABASE_ABORTED; 395*cdf0e10cSrcweir } 396*cdf0e10cSrcweir } 397*cdf0e10cSrcweir } 398*cdf0e10cSrcweir else // past the end of the spreadsheet 399*cdf0e10cSrcweir { 400*cdf0e10cSrcweir bEnd = sal_True; // don't continue 401*cdf0e10cSrcweir bTruncated = sal_True; // warning flag 402*cdf0e10cSrcweir } 403*cdf0e10cSrcweir } 404*cdf0e10cSrcweir } 405*cdf0e10cSrcweir 406*cdf0e10cSrcweir bSuccess = sal_True; 407*cdf0e10cSrcweir } 408*cdf0e10cSrcweir 409*cdf0e10cSrcweir if ( bDispose ) 410*cdf0e10cSrcweir ::comphelper::disposeComponent( xRowSet ); 411*cdf0e10cSrcweir } 412*cdf0e10cSrcweir } 413*cdf0e10cSrcweir catch ( sdbc::SQLException& rError ) 414*cdf0e10cSrcweir { 415*cdf0e10cSrcweir aErrorMessage = rError.Message; 416*cdf0e10cSrcweir } 417*cdf0e10cSrcweir catch ( uno::Exception& ) 418*cdf0e10cSrcweir { 419*cdf0e10cSrcweir DBG_ERROR("Unexpected exception in database"); 420*cdf0e10cSrcweir } 421*cdf0e10cSrcweir 422*cdf0e10cSrcweir ScColumn::bDoubleAlloc = sal_False; 423*cdf0e10cSrcweir pImportDoc->DoColResize( nTab, rParam.nCol1,nEndCol, 0 ); 424*cdf0e10cSrcweir 425*cdf0e10cSrcweir // 426*cdf0e10cSrcweir // test for cell protection 427*cdf0e10cSrcweir // 428*cdf0e10cSrcweir 429*cdf0e10cSrcweir sal_Bool bKeepFormat = !bAddrInsert && pDBData->IsKeepFmt(); 430*cdf0e10cSrcweir sal_Bool bMoveCells = !bAddrInsert && pDBData->IsDoSize(); 431*cdf0e10cSrcweir SCCOL nFormulaCols = 0; // columns to be filled with formulas 432*cdf0e10cSrcweir if (bMoveCells && nEndCol == rParam.nCol2) 433*cdf0e10cSrcweir { 434*cdf0e10cSrcweir // if column count changes, formulas would become invalid anyway 435*cdf0e10cSrcweir // -> only set nFormulaCols for unchanged column count 436*cdf0e10cSrcweir 437*cdf0e10cSrcweir SCCOL nTestCol = rParam.nCol2 + 1; // right of the data 438*cdf0e10cSrcweir SCROW nTestRow = rParam.nRow1 + 1; // below the title row 439*cdf0e10cSrcweir while ( nTestCol <= MAXCOL && 440*cdf0e10cSrcweir pDoc->GetCellType(ScAddress( nTestCol, nTestRow, nTab )) == CELLTYPE_FORMULA ) 441*cdf0e10cSrcweir ++nTestCol, ++nFormulaCols; 442*cdf0e10cSrcweir } 443*cdf0e10cSrcweir 444*cdf0e10cSrcweir if (bSuccess) 445*cdf0e10cSrcweir { 446*cdf0e10cSrcweir // old and new range editable? 447*cdf0e10cSrcweir ScEditableTester aTester; 448*cdf0e10cSrcweir aTester.TestBlock( pDoc, nTab, rParam.nCol1,rParam.nRow1,rParam.nCol2,rParam.nRow2 ); 449*cdf0e10cSrcweir aTester.TestBlock( pDoc, nTab, rParam.nCol1,rParam.nRow1,nEndCol,nEndRow ); 450*cdf0e10cSrcweir if ( !aTester.IsEditable() ) 451*cdf0e10cSrcweir { 452*cdf0e10cSrcweir nErrStringId = aTester.GetMessageId(); 453*cdf0e10cSrcweir bSuccess = sal_False; 454*cdf0e10cSrcweir } 455*cdf0e10cSrcweir else if ( pDoc->GetChangeTrack() != NULL ) 456*cdf0e10cSrcweir { 457*cdf0e10cSrcweir nErrStringId = STR_PROTECTIONERR; 458*cdf0e10cSrcweir bSuccess = sal_False; 459*cdf0e10cSrcweir } 460*cdf0e10cSrcweir } 461*cdf0e10cSrcweir 462*cdf0e10cSrcweir if ( bSuccess && bMoveCells ) 463*cdf0e10cSrcweir { 464*cdf0e10cSrcweir ScRange aOld( rParam.nCol1, rParam.nRow1, nTab, 465*cdf0e10cSrcweir rParam.nCol2+nFormulaCols, rParam.nRow2, nTab ); 466*cdf0e10cSrcweir ScRange aNew( rParam.nCol1, rParam.nRow1, nTab, 467*cdf0e10cSrcweir nEndCol+nFormulaCols, nEndRow, nTab ); 468*cdf0e10cSrcweir if (!pDoc->CanFitBlock( aOld, aNew )) 469*cdf0e10cSrcweir { 470*cdf0e10cSrcweir nErrStringId = STR_MSSG_DOSUBTOTALS_2; // can't insert cells 471*cdf0e10cSrcweir bSuccess = sal_False; 472*cdf0e10cSrcweir } 473*cdf0e10cSrcweir } 474*cdf0e10cSrcweir 475*cdf0e10cSrcweir // 476*cdf0e10cSrcweir // copy data from import doc into real document 477*cdf0e10cSrcweir // 478*cdf0e10cSrcweir 479*cdf0e10cSrcweir if ( bSuccess ) 480*cdf0e10cSrcweir { 481*cdf0e10cSrcweir if (bKeepFormat) 482*cdf0e10cSrcweir { 483*cdf0e10cSrcweir // keep formatting of title and first data row from the document 484*cdf0e10cSrcweir // CopyToDocument also copies styles, Apply... needs separate calls 485*cdf0e10cSrcweir 486*cdf0e10cSrcweir SCCOL nMinEndCol = Min( rParam.nCol2, nEndCol ); // not too much 487*cdf0e10cSrcweir nMinEndCol = sal::static_int_cast<SCCOL>( nMinEndCol + nFormulaCols ); // only if column count unchanged 488*cdf0e10cSrcweir pImportDoc->DeleteAreaTab( 0,0, MAXCOL,MAXROW, nTab, IDF_ATTRIB ); 489*cdf0e10cSrcweir pDoc->CopyToDocument( rParam.nCol1, rParam.nRow1, nTab, 490*cdf0e10cSrcweir nMinEndCol, rParam.nRow1, nTab, 491*cdf0e10cSrcweir IDF_ATTRIB, sal_False, pImportDoc ); 492*cdf0e10cSrcweir 493*cdf0e10cSrcweir SCROW nDataStartRow = rParam.nRow1+1; 494*cdf0e10cSrcweir for (SCCOL nCopyCol=rParam.nCol1; nCopyCol<=nMinEndCol; nCopyCol++) 495*cdf0e10cSrcweir { 496*cdf0e10cSrcweir const ScPatternAttr* pSrcPattern = pDoc->GetPattern( 497*cdf0e10cSrcweir nCopyCol, nDataStartRow, nTab ); 498*cdf0e10cSrcweir pImportDoc->ApplyPatternAreaTab( nCopyCol, nDataStartRow, nCopyCol, nEndRow, 499*cdf0e10cSrcweir nTab, *pSrcPattern ); 500*cdf0e10cSrcweir const ScStyleSheet* pStyle = pSrcPattern->GetStyleSheet(); 501*cdf0e10cSrcweir if (pStyle) 502*cdf0e10cSrcweir pImportDoc->ApplyStyleAreaTab( nCopyCol, nDataStartRow, nCopyCol, nEndRow, 503*cdf0e10cSrcweir nTab, *pStyle ); 504*cdf0e10cSrcweir } 505*cdf0e10cSrcweir } 506*cdf0e10cSrcweir 507*cdf0e10cSrcweir // don't set cell protection attribute if table is protected 508*cdf0e10cSrcweir if (pDoc->IsTabProtected(nTab)) 509*cdf0e10cSrcweir { 510*cdf0e10cSrcweir ScPatternAttr aPattern(pImportDoc->GetPool()); 511*cdf0e10cSrcweir aPattern.GetItemSet().Put( ScProtectionAttr( sal_False,sal_False,sal_False,sal_False ) ); 512*cdf0e10cSrcweir pImportDoc->ApplyPatternAreaTab( 0,0,MAXCOL,MAXROW, nTab, aPattern ); 513*cdf0e10cSrcweir } 514*cdf0e10cSrcweir 515*cdf0e10cSrcweir // 516*cdf0e10cSrcweir // copy old data for undo 517*cdf0e10cSrcweir // 518*cdf0e10cSrcweir 519*cdf0e10cSrcweir SCCOL nUndoEndCol = Max( nEndCol, rParam.nCol2 ); // rParam = old end 520*cdf0e10cSrcweir SCROW nUndoEndRow = Max( nEndRow, rParam.nRow2 ); 521*cdf0e10cSrcweir 522*cdf0e10cSrcweir ScDocument* pUndoDoc = NULL; 523*cdf0e10cSrcweir ScDBData* pUndoDBData = NULL; 524*cdf0e10cSrcweir if ( bRecord ) 525*cdf0e10cSrcweir { 526*cdf0e10cSrcweir pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); 527*cdf0e10cSrcweir pUndoDoc->InitUndo( pDoc, nTab, nTab ); 528*cdf0e10cSrcweir 529*cdf0e10cSrcweir if ( !bAddrInsert ) 530*cdf0e10cSrcweir pUndoDBData = new ScDBData( *pDBData ); 531*cdf0e10cSrcweir } 532*cdf0e10cSrcweir 533*cdf0e10cSrcweir ScMarkData aNewMark; 534*cdf0e10cSrcweir aNewMark.SelectOneTable( nTab ); 535*cdf0e10cSrcweir 536*cdf0e10cSrcweir if (bRecord) 537*cdf0e10cSrcweir { 538*cdf0e10cSrcweir // do not touch notes (ScUndoImportData does not support drawing undo) 539*cdf0e10cSrcweir sal_uInt16 nCopyFlags = IDF_ALL & ~IDF_NOTE; 540*cdf0e10cSrcweir 541*cdf0e10cSrcweir // nFormulaCols is set only if column count is unchanged 542*cdf0e10cSrcweir pDoc->CopyToDocument( rParam.nCol1, rParam.nRow1, nTab, 543*cdf0e10cSrcweir nEndCol+nFormulaCols, nEndRow, nTab, 544*cdf0e10cSrcweir nCopyFlags, sal_False, pUndoDoc ); 545*cdf0e10cSrcweir if ( rParam.nCol2 > nEndCol ) 546*cdf0e10cSrcweir pDoc->CopyToDocument( nEndCol+1, rParam.nRow1, nTab, 547*cdf0e10cSrcweir nUndoEndCol, nUndoEndRow, nTab, 548*cdf0e10cSrcweir nCopyFlags, sal_False, pUndoDoc ); 549*cdf0e10cSrcweir if ( rParam.nRow2 > nEndRow ) 550*cdf0e10cSrcweir pDoc->CopyToDocument( rParam.nCol1, nEndRow+1, nTab, 551*cdf0e10cSrcweir nUndoEndCol+nFormulaCols, nUndoEndRow, nTab, 552*cdf0e10cSrcweir nCopyFlags, sal_False, pUndoDoc ); 553*cdf0e10cSrcweir } 554*cdf0e10cSrcweir 555*cdf0e10cSrcweir // 556*cdf0e10cSrcweir // move new data 557*cdf0e10cSrcweir // 558*cdf0e10cSrcweir 559*cdf0e10cSrcweir if (bMoveCells) 560*cdf0e10cSrcweir { 561*cdf0e10cSrcweir // clear only the range without the formulas, 562*cdf0e10cSrcweir // so the formula title and first row are preserved 563*cdf0e10cSrcweir 564*cdf0e10cSrcweir ScRange aDelRange( rParam.nCol1, rParam.nRow1, nTab, 565*cdf0e10cSrcweir rParam.nCol2, rParam.nRow2, nTab ); 566*cdf0e10cSrcweir pDoc->DeleteAreaTab( aDelRange, IDF_ALL & ~IDF_NOTE ); // ohne die Formeln 567*cdf0e10cSrcweir 568*cdf0e10cSrcweir ScRange aOld( rParam.nCol1, rParam.nRow1, nTab, 569*cdf0e10cSrcweir rParam.nCol2+nFormulaCols, rParam.nRow2, nTab ); 570*cdf0e10cSrcweir ScRange aNew( rParam.nCol1, rParam.nRow1, nTab, 571*cdf0e10cSrcweir nEndCol+nFormulaCols, nEndRow, nTab ); 572*cdf0e10cSrcweir pDoc->FitBlock( aOld, aNew, sal_False ); // Formeln nicht loeschen 573*cdf0e10cSrcweir } 574*cdf0e10cSrcweir else if ( nEndCol < rParam.nCol2 ) // DeleteArea calls PutInOrder 575*cdf0e10cSrcweir pDoc->DeleteArea( nEndCol+1, rParam.nRow1, rParam.nCol2, rParam.nRow2, 576*cdf0e10cSrcweir aNewMark, IDF_CONTENTS & ~IDF_NOTE ); 577*cdf0e10cSrcweir 578*cdf0e10cSrcweir // CopyToDocument doesn't remove contents 579*cdf0e10cSrcweir pDoc->DeleteAreaTab( rParam.nCol1, rParam.nRow1, nEndCol, nEndRow, nTab, IDF_CONTENTS & ~IDF_NOTE ); 580*cdf0e10cSrcweir 581*cdf0e10cSrcweir // #41216# remove each column from ImportDoc after copying to reduce memory usage 582*cdf0e10cSrcweir sal_Bool bOldAutoCalc = pDoc->GetAutoCalc(); 583*cdf0e10cSrcweir pDoc->SetAutoCalc( sal_False ); // outside of the loop 584*cdf0e10cSrcweir for (SCCOL nCopyCol = rParam.nCol1; nCopyCol <= nEndCol; nCopyCol++) 585*cdf0e10cSrcweir { 586*cdf0e10cSrcweir pImportDoc->CopyToDocument( nCopyCol, rParam.nRow1, nTab, nCopyCol, nEndRow, nTab, 587*cdf0e10cSrcweir IDF_ALL, sal_False, pDoc ); 588*cdf0e10cSrcweir pImportDoc->DeleteAreaTab( nCopyCol, rParam.nRow1, nCopyCol, nEndRow, nTab, IDF_CONTENTS ); 589*cdf0e10cSrcweir pImportDoc->DoColResize( nTab, nCopyCol, nCopyCol, 0 ); 590*cdf0e10cSrcweir } 591*cdf0e10cSrcweir pDoc->SetAutoCalc( bOldAutoCalc ); 592*cdf0e10cSrcweir 593*cdf0e10cSrcweir if (nFormulaCols > 0) // copy formulas 594*cdf0e10cSrcweir { 595*cdf0e10cSrcweir if (bKeepFormat) // formats for formulas 596*cdf0e10cSrcweir pImportDoc->CopyToDocument( nEndCol+1, rParam.nRow1, nTab, 597*cdf0e10cSrcweir nEndCol+nFormulaCols, nEndRow, nTab, 598*cdf0e10cSrcweir IDF_ATTRIB, sal_False, pDoc ); 599*cdf0e10cSrcweir // fill formulas 600*cdf0e10cSrcweir ScMarkData aMark; 601*cdf0e10cSrcweir aMark.SelectOneTable(nTab); 602*cdf0e10cSrcweir pDoc->Fill( nEndCol+1, rParam.nRow1+1, nEndCol+nFormulaCols, rParam.nRow1+1, 603*cdf0e10cSrcweir aMark, nEndRow-rParam.nRow1-1, FILL_TO_BOTTOM, FILL_SIMPLE ); 604*cdf0e10cSrcweir } 605*cdf0e10cSrcweir 606*cdf0e10cSrcweir // if new range is smaller, clear old contents 607*cdf0e10cSrcweir 608*cdf0e10cSrcweir if (!bMoveCells) // move has happened above 609*cdf0e10cSrcweir { 610*cdf0e10cSrcweir if ( rParam.nCol2 > nEndCol ) 611*cdf0e10cSrcweir pDoc->DeleteArea( nEndCol+1, rParam.nRow1, rParam.nCol2, rParam.nRow2, 612*cdf0e10cSrcweir aNewMark, IDF_CONTENTS ); 613*cdf0e10cSrcweir if ( rParam.nRow2 > nEndRow ) 614*cdf0e10cSrcweir pDoc->DeleteArea( rParam.nCol1, nEndRow+1, rParam.nCol2, rParam.nRow2, 615*cdf0e10cSrcweir aNewMark, IDF_CONTENTS ); 616*cdf0e10cSrcweir } 617*cdf0e10cSrcweir 618*cdf0e10cSrcweir if( !bAddrInsert ) // update database range 619*cdf0e10cSrcweir { 620*cdf0e10cSrcweir pDBData->SetImportParam( rParam ); 621*cdf0e10cSrcweir pDBData->SetHeader( sal_True ); 622*cdf0e10cSrcweir pDBData->SetByRow( sal_True ); 623*cdf0e10cSrcweir pDBData->SetArea( nTab, rParam.nCol1,rParam.nRow1, nEndCol,nEndRow ); 624*cdf0e10cSrcweir pDBData->SetImportSelection( bRealSelection ); 625*cdf0e10cSrcweir pDoc->CompileDBFormula(); 626*cdf0e10cSrcweir } 627*cdf0e10cSrcweir 628*cdf0e10cSrcweir if (bRecord) 629*cdf0e10cSrcweir { 630*cdf0e10cSrcweir ScDocument* pRedoDoc = pImportDoc; 631*cdf0e10cSrcweir pImportDoc = NULL; 632*cdf0e10cSrcweir 633*cdf0e10cSrcweir if (nFormulaCols > 0) // include filled formulas for redo 634*cdf0e10cSrcweir pDoc->CopyToDocument( rParam.nCol1, rParam.nRow1, nTab, 635*cdf0e10cSrcweir nEndCol+nFormulaCols, nEndRow, nTab, 636*cdf0e10cSrcweir IDF_ALL & ~IDF_NOTE, sal_False, pRedoDoc ); 637*cdf0e10cSrcweir 638*cdf0e10cSrcweir ScDBData* pRedoDBData = pDBData ? new ScDBData( *pDBData ) : NULL; 639*cdf0e10cSrcweir 640*cdf0e10cSrcweir rDocShell.GetUndoManager()->AddUndoAction( 641*cdf0e10cSrcweir new ScUndoImportData( &rDocShell, nTab, 642*cdf0e10cSrcweir rParam, nUndoEndCol, nUndoEndRow, 643*cdf0e10cSrcweir nFormulaCols, 644*cdf0e10cSrcweir pUndoDoc, pRedoDoc, pUndoDBData, pRedoDBData ) ); 645*cdf0e10cSrcweir } 646*cdf0e10cSrcweir 647*cdf0e10cSrcweir pDoc->SetDirty(); 648*cdf0e10cSrcweir rDocShell.PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID ); 649*cdf0e10cSrcweir aModificator.SetDocumentModified(); 650*cdf0e10cSrcweir 651*cdf0e10cSrcweir ScDBRangeRefreshedHint aHint( rParam ); 652*cdf0e10cSrcweir pDoc->BroadcastUno( aHint ); 653*cdf0e10cSrcweir 654*cdf0e10cSrcweir if (pWaitWin) 655*cdf0e10cSrcweir pWaitWin->LeaveWait(); 656*cdf0e10cSrcweir 657*cdf0e10cSrcweir if ( bTruncated && !bApi ) // show warning 658*cdf0e10cSrcweir ErrorHandler::HandleError(SCWARN_IMPORT_RANGE_OVERFLOW); 659*cdf0e10cSrcweir } 660*cdf0e10cSrcweir else if ( !bApi ) 661*cdf0e10cSrcweir { 662*cdf0e10cSrcweir if (pWaitWin) 663*cdf0e10cSrcweir pWaitWin->LeaveWait(); 664*cdf0e10cSrcweir 665*cdf0e10cSrcweir if (!aErrorMessage.Len()) 666*cdf0e10cSrcweir { 667*cdf0e10cSrcweir if (!nErrStringId) 668*cdf0e10cSrcweir nErrStringId = STR_MSSG_IMPORTDATA_0; 669*cdf0e10cSrcweir aErrorMessage = ScGlobal::GetRscString( nErrStringId ); 670*cdf0e10cSrcweir } 671*cdf0e10cSrcweir InfoBox aInfoBox( rDocShell.GetActiveDialogParent(), aErrorMessage ); 672*cdf0e10cSrcweir aInfoBox.Execute(); 673*cdf0e10cSrcweir } 674*cdf0e10cSrcweir 675*cdf0e10cSrcweir delete pImportDoc; 676*cdf0e10cSrcweir 677*cdf0e10cSrcweir return bSuccess; 678*cdf0e10cSrcweir } 679*cdf0e10cSrcweir 680*cdf0e10cSrcweir 681*cdf0e10cSrcweir 682*cdf0e10cSrcweir 683